python3多线程爬虫实现异步更新代理池

探讨了在大数据分析系统中,使用Python爬虫抓取100万条数据的挑战与解决方案,包括多线程爬取、代理IP管理和锁机制协调。

这几天要搞毕业设计,一个简单的大数据分析系统,既然是大数据分析系统,那么一定要有数据,目标是用python写一个爬虫,爬大约100w条数据

这就遇到了第一个问题,100w条数据单线程的话需要爬很久,所以要用多线程获取,这又会有一个新问题,爬取频率过高的话会被封ip,所以要使用https代理(貌似http不行,会被查出来)
然后又出现一个问题,免费的代理稳定性太差,而且访问速度慢,自己写了个爬虫获取免费代理然后进行测试,能稳定使用的大概只有2成,干脆就用付费的吧,平均一元100个左右,不算太贵

然后又出了问题,付费的虽然稳定,但也只是相对的,依然会有将近一成无法使用,而能用的会在半小时之内的某个时间失效(不确定失效时间这一点很蛋疼),大量数据需要多线程爬取很长的时间,怎么能在这么长的时间保持稳定就成了一大问题

单线程很好说,先获取一定数量的代理,从中选一个用做代理,不能使用就去掉,每个都不能用了再获取,不过这样会有一个问题,代理有的能维持5分钟,有的能维持30分钟,假设获取了5个代理,第一次就选了能用30分钟的代理,其余4个就白获取了,很浪费,而且还要对剩余4个一个一个检测是否能用,相当费时间,最好的方法是一次只申请一个

多线程就不行了,假如我开了20个线程的话,总共每轮要获取20次代理,浪费时间不说,如果同时获取,还容易引发错误或者被代理网站当做恶意访问。干脆一次多获取一些,用全局变量储存,每次网络请求时就从全局变量中选一个,不能访问就去除,不够用了就再获取少量代理,但是多线程对全局变量进行操作就会引发冲突,比如线程1发现第一个代理不能用的同时线程2也发现了,线程1去除坏代理之后线程2再试图去除时就会产生error,按下标去除的话可能会把能用的代理去除,所以多线程怎么协调就成了一个问题。

解决方法比较简单
利用锁,改变公共资源前获取锁,完成后释放锁
每个线程在进行网络请求时,先获取锁,从全局变量中pop一个,如果全局变量中代理不够,再从网上获取代理,再释放锁,代理能用的话再append()回全局变量,不能用的话直接return递归函数(不能用的那个已经不在全局变量中了)
代码
部分代码没有写出来,我是用bs4分析网页的,所有对网页的get请求都会用到get_bsobj(url),爬了几万个暂时没有问题,20个线程还是很快的,理论上还可以加,明天继续搞

threadLock = threading.Lock()
pro=[]
Cookie=''
wait =(1,9)
def get_proxies_list(num):
    global pro
    pro+=requests.get(url='https://xxx.xxxxxxxx.xxx&num='+str(num))#通过某些手段获取了一定数量的代理
    return 
def set_proxies():
    global wait,pro
    # time.sleep(random.randint(wait[0],wait[1]))
    threadLock.acquire()#获取锁
    if pro==[]:
        get_proxies_list(10)
    i=pro.pop(0)
    threadLock.release()#释放锁
    return pro
def get_bsobj(url): 
    global Cookie,pro
    u=0
    p=set_proxies()
    headers =set_header(Cookie)
    while u<3:#检测次数,超过timout时限u次便认为代理失效
        try:
            html=requests.get(url,headers=headers, proxies ={'https':p},timeout=5)#检测时间超过timout的话会认为请求失败
            BsObj=BeautifulSoup(html.text,"html.parser")
            pro.append(p) 
            return BsObj
        except:
            u=u+1

    
    return get_bsobj(url)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值