前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >爬虫代理

爬虫代理

作者头像
K同学啊
发布2019-01-22 11:28:15
7230
发布2019-01-22 11:28:15
举报

前言

花了几天时间写了一个比较完整的爬虫代理模块,基本上实现了一个比较完整的代理系统。

有如下几大模块:

  • ip的获取模块
  • 检验及删除更新
  • requests循环请求

ip的获取

ip来源:http://www.xicidaili.com/wt/ 通过遍历西刺代理中的四个页面获取ip,然后对ip有效性进行检验,将有效的ip写入文件。这里需要注意一下,西刺代理有效的ip一般都在前面,后面基本都是失效了的,我选择每个页面的前30条ip地址来检验,后面的直接舍弃。

代码语言:javascript
复制
    #http://www.xicidaili.com/wt/
    def get_goubanjia(self,url_target):
        try:
            #设置headers
            headers = {'User-Agent':str(UserAgent().random)}
            #发送requests请求
            req = requests.get(url_target,headers=headers, timeout=5)
            #校正网页编码
            req.encoding = req.apparent_encoding
            #对网页进行解析
            soup = BeautifulSoup(req.text, 'lxml')
            tr_list = soup.find_all('tr')

            for each in range(1, 31):
                print('已经筛选了{}条ip'.format(each))
                print("获取地址")
                #获取地址
                td = tr_list[each].find_all('td')
                a = td[1].get_text()
                print("获取端口")
                #获取端口
                b = td[2].get_text()
                #将有效的ip写入文件
                proxy = 'http://' + a+':'+b
                #检验ip是否有效,将有效的ip写入文件当中
                if self.verifyIP(proxy):
                    f = open('ip.txt','a+',encoding='utf-8')
                    f.write(proxy+'\n')
                    f.close()
                #输出爬取到的信息
                print(proxy)
        except Exception as e:
            print(str(e))
            print('{}:网站页面发生变动,请及时更新'.format(url_target))

ip的检验

通过传入的proxy(‘http://123.123.123‘),利用需要爬取的网站作为目标网站,发送requests请求来实现ip有效性的检验。 在检验ip有效性的过程中,我发现了这样一个有趣的现象,同一批ip对不同网站的访问速度不同(排除了网站本身的访问速度原因)。打个比方,有A、B两个网站他们的服务器配置是一样的,但是a、b、c、d四个ip从发送请求到相应这中间的时间却是不一样的。 所以,建议检验ip有效性时采用目标网站比较合适

代码语言:javascript
复制
    #验证ip,返回True/False值
    def verifyIP(self,proxy):
        print('开始判断{}的有效性'.format(proxy))
        try:
            #设置ip
            proxies = {'{}'.format(self.ip_stype):proxy}
            #设置headers
            headers = {'User-Agent':str(UserAgent().random)}
            #发生requests请求
            req = requests.get(self.url, headers=headers, proxies=proxies, verify=False, timeout=(6,14))
        except Exception as e:
            print('{}代理ip无效'.format(proxies))
            print('在检验过程中遇到的requests错误原因是:{}'.format(e))
            return False
        else:
            print('{}代理ip有效'.format(proxies))
            return True
        finally:
            print('{}代理ip有效性判断完成'.format(proxies))

删除ip

删除ip这块相对而言简单一些,读取文件–>删除旧文件–>删除ip列表中的失效ip–>将ip列表写入文件。

代码语言:javascript
复制
    #删除proxy
    def deleteProxy(self,proxy):
        print('删除无效proxy:{}'.format(proxy))
        f = open('ip.txt', 'r', encoding='utf-8')
        proxy_list = f.readlines()
        f.close()
        #删除列表中的换行符号
        proxy_list = [proxy.replace('\n','') for proxy in proxy_list]
        #删除原文件
        os.remove('ip.txt')
        #删除指定的proxy
        proxy_list.remove(proxy)
        #当文件为空时,重新下载文件
        if len(proxy_list)==0:
            print('现在列表为空,我们将重新获取ip')
            #调用父类下载新的ip文件
            super().getIpFile()
        #将信息重新写入文件
        f = open('ip.txt', 'a+', encoding='utf-8')
        for each in proxy_list:
            f.write(each+'\n')
        f.close()

ip文件的自动更新机制

简单点来说就是在删除失效ip后检测文件是否为空,为空时,再次从互联网上下载一批新的ip

代码语言:javascript
复制
    #删除指定的proxy
    proxy_list.remove(proxy)
    #当文件为空时,重新下载文件
    if len(proxy_list)==0:
        print('现在列表为空,我们将重新获取ip')
        #调用父类下载新的ip文件
        super().getIpFile()

requests循环请求

利用while构造一个死循环,只有在requests请求成功时,打破死循环的代码(flag=False)才会被执行,当然每一次循环都会采用新的IP地址以及headers

代码语言:javascript
复制
flag=True
while (flag!=False):
    try:
        try:
            #设置代理ip
            proxy = self.createRandomIp()
            #设置proxies
            proxies = {'{}'.format(self.ip_stype):proxy}
            #设置代理headers
            headers = {'User-Agent':str(UserAgent().random)}
            req = requests.get(self.url, proxies=proxies, headers=headers, verify=False, timeout=(9,21))
            flag=False
        except Exception as e:
            print('上一次请求失败,10秒后我们将进行下一次请求')
            print("上一次requests请求失败的原因是{}".format(e))
            print('上一次请求的代理ip为:{}'.format(proxy))
            time.sleep(10)
            #验证proxy的有效性,并对无效proxy进行处理
            proxy = self.verifyProxy(proxy)
            #设置proxies
            proxies = {'{}'.format(self.ip_stype):proxy}
            #设置代理headers
            headers = {'User-Agent':str(UserAgent().random)}
            req = requests.get(self.url, proxies=proxies, headers=headers, verify=False, timeout=(9,21))
            flag=False
    except:
        pass

备注

考虑到短时间多次访问一个网站可能会被识别出来,故在第一次发送requests请求时是不检验ip的有效性,如果请求出错则10秒后会对该ip进行验证,中间间隔10秒是考虑到网络信号的影响。如果检验到ip失效则会将其从ip文件中删除。

在删除失效ip后,会重新分配一个ip并对其有效性进行检验,无效则删除,重新分配ip直至分配的ip通过检验,采用的是递归算法。

在requests请求这一块,也具有相同的思想,不断发送requests请求直至成功,采用while构造死循环。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年08月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • ip的获取
  • ip的检验
  • 删除ip
  • ip文件的自动更新机制
  • requests循环请求
  • 备注
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档