详解爬虫被封的问题


Posted in Python onApril 23, 2019

如果你在爬虫过程中有遇到“您的请求太过频繁,请稍后再试”,或者说代码完全正确,可是爬虫过程中突然就访问不了,那么恭喜你,你的爬虫被对方识破了,轻则给予友好提示警告,严重的可能会对你的ip进行封禁,所以代理ip那就尤为重要了。今天我们就来谈一下代理IP,去解决爬虫被封的问题。

网上有许多代理ip,免费的、付费的。大多数公司爬虫会买这些专业版,对于普通人来说,免费的基本满足我们需要了,不过免费有一个弊端,时效性不强,不稳定,所以我们就需要对采集的ip进行一个简单的验证。

1.目标采集

本文主要针对西刺代理,这个网站很早之前用过,不过那个时候它还提供免费的api,现在api暂不提供了,我们就写个简单的爬虫去采集。

打开西刺代理,有几个页面,果断选择高匿代理。

详解爬虫被封的问题

Chrome浏览器右键检查查看network,不难发现,每个ip地址都在td标签中,对于我们来说就简单许多了,初步的想法就是获取所有的ip,然后校验可用性,不可用就剔除。

 详解爬虫被封的问题

 定义匹配规则

import re

ip_compile = re.compile(r'<td>(\d+\.\d+\.\d+\.\d+)</td>') # 匹配IP
port_compile = re.compile(r'<td>(\d+)</td>') # 匹配端口

 2.校验 这里我使用淘宝ip地址库检验可用性

2.1、关于淘宝IP地址库

目前提供的服务包括:

  1. 1. 根据用户提供的IP地址,快速查询出该IP地址所在的地理信息和地理相关的信息,包括国家、省、市和运营商。
  2. 2. 用户可以根据自己所在的位置和使用的IP地址更新我们的服务内容。

我们的优势:

  1. 1. 提供国家、省、市、县、运营商全方位信息,信息维度广,格式规范。
  2. 2. 提供完善的统计分析报表,省准确度超过99.8%,市准确度超过96.8%,数据质量有保障。

2.2、接口说明

请求接口(GET):
ip.taobao.com/service/get…
例:http://ip.taobao.com/service/getIpInfo2.php?ip=111.177.181.44
响应信息:
(json格式的)国家 、省(自治区或直辖市)、市(县)、运营商
返回数据格式:

{"code":0,"data":{"ip":"210.75.225.254","country":"\u4e2d\u56fd","area":"\u534e\u5317",
"region":"\u5317\u4eac\u5e02","city":"\u5317\u4eac\u5e02","county":"","isp":"\u7535\u4fe1",
"country_id":"86","area_id":"100000","region_id":"110000","city_id":"110000",
"county_id":"-1","isp_id":"100017"}}

其中code的值的含义为,0:成功,1:失败。
注意:为了保障服务正常运行,每个用户的访问频率需小于10qps。
我们先通过浏览器测试一下

输入地址http://ip.taobao.com/service/getIpInfo2.php?ip=111.177.181.44

详解爬虫被封的问题

再次输入一个地址http://ip.taobao.com/service/getIpInfo2.php?ip=112.85.168.98

详解爬虫被封的问题

代码操作

import requests

check_api = "http://ip.taobao.com/service/getIpInfo2.php?ip="
api = check_api + ip
try:
  response = requests.get(url=api, headers=api_headers, timeout=2)
  print("ip:%s 可用" % ip)
except Exception as e:
  print("此ip %s 已失效:%s" % (ip, e))

 3.代码
代码中加入了异常处理,其实自己手写的demo写不写异常处理都可以,但是为了方便其他人调试,建议在可能出现异常的地方加入异常处理。

import requests
import re
import random

from bs4 import BeautifulSoup

ua_list = [
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36",
  "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36",
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36",
  "Mozilla / 5.0(Windows NT 6.1;WOW64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 45.0.2454.101Safari / 537.36"
  ]


def ip_parse_xici(page):
  """

  :param page: 采集的页数
  :return:
  """
  ip_list = []
  for pg in range(1, int(page)):
    url = 'http://www.xicidaili.com/nn/' + str(pg)
    user_agent = random.choice(ua_list)
    my_headers = {
      'Accept': 'text/html, application/xhtml+xml, application/xml;',
      'Accept-Encoding': 'gzip, deflate, sdch',
      'Accept-Language': 'zh-CN,zh;q=0.8',
      'Referer': 'http: // www.xicidaili.com/nn',
      'User-Agent': user_agent
    }
    try:
      r = requests.get(url, headers=my_headers)
      soup = BeautifulSoup(r.text, 'html.parser')
    except requests.exceptions.ConnectionError:
      print('ConnectionError')
    else:
      data = soup.find_all('td')
      # 定义IP和端口Pattern规则
      ip_compile = re.compile(r'<td>(\d+\.\d+\.\d+\.\d+)</td>') # 匹配IP
      port_compile = re.compile(r'<td>(\d+)</td>') # 匹配端口
      ips = re.findall(ip_compile, str(data)) # 获取所有IP

      ports = re.findall(port_compile, str(data)) # 获取所有端口
      check_api = "http://ip.taobao.com/service/getIpInfo2.php?ip="

      for i in range(len(ips)):
        if i < len(ips):
          ip = ips[i]
          api = check_api + ip
          api_headers = {
            'User-Agent': user_agent
          }
          try:
            response = requests.get(url=api, headers=api_headers, timeout=2)
            print("ip:%s 可用" % ip)
          except Exception as e:
            print("此ip %s 已失效:%s" % (ip, e))
            del ips[i]
            del ports[i]
      ips_usable = ips
      ip_list += [':'.join(n) for n in zip(ips_usable, ports)] # 列表生成式
      print('第{}页ip采集完成'.format(pg))
  print(ip_list)


if __name__ == '__main__':
  xici_pg = input("请输入需要采集的页数:")
  ip_parse_xici(page=xici_pg)

运行代码:

详解爬虫被封的问题

4.为你的爬虫加入代理ip

建议大家可以把采集的ip存入数据库,这样每次爬虫的时候直接调用即可,顺便提一下代码中怎么加入代理ip。

import requests

url = 'www.baidu.com'
headers = {
  "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36",
}
proxies = {
  "http": "http://111.177.181.44:9999",
  # "https": "https://111.177.181.44:9999",
}

res = requests.get(url=url, headers=headers, proxies=proxies)

好了,妈妈再也不担心我爬虫被封了

以上所述是小编给大家介绍的爬虫被封的问题详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python读取一个目录下所有目录和文件的方法
Jul 15 Python
浅析Python中元祖、列表和字典的区别
Aug 17 Python
Python爬虫利用cookie实现模拟登陆实例详解
Jan 12 Python
Python 数据结构之旋转链表
Feb 25 Python
Python升级导致yum、pip报错的解决方法
Sep 06 Python
Python中Threading用法详解
Dec 27 Python
wxPython之解决闪烁的问题
Jan 15 Python
python爬取网页转换为PDF文件
Jun 07 Python
浅谈python 读excel数值为浮点型的问题
Dec 25 Python
Python 多线程搜索txt文件的内容,并写入搜到的内容(Lock)方法
Aug 23 Python
python GUI库图形界面开发之PyQt5 UI主线程与耗时线程分离详细方法实例
Feb 26 Python
Python数据可视化常用4大绘图库原理详解
Oct 23 Python
Python3.5 Pandas模块缺失值处理和层次索引实例详解
Apr 23 #Python
Python3.5 Pandas模块之DataFrame用法实例分析
Apr 23 #Python
Python3.5 Pandas模块之Series用法实例分析
Apr 23 #Python
使用Python控制摄像头拍照并发邮件
Apr 23 #Python
详解Python静态网页爬取获取高清壁纸
Apr 23 #Python
Python matplotlib画图与中文设置操作实例分析
Apr 23 #Python
Python实现的删除重复文件或图片功能示例【去重】
Apr 23 #Python
You might like
通过JavaScript或PHP检测Android设备的代码
2011/03/09 PHP
php生成缩略图填充白边(等比缩略图方案)
2013/12/25 PHP
php获取文件夹路径内的图片以及分页显示示例
2014/03/11 PHP
PHP之预定义接口详解
2015/07/29 PHP
php 数据结构之链表队列
2017/10/17 PHP
JQuery Dialog(JS 模态窗口,可拖拽的DIV)
2010/02/07 Javascript
JS仿flash上传头像效果实现代码
2011/07/18 Javascript
ExtJs Excel导出并下载IIS服务器端遇到的问题
2011/09/16 Javascript
js遍历、动态的添加数据的小例子
2013/06/22 Javascript
js获取html页面节点方法(递归方式)
2013/12/13 Javascript
Array栈方法和队列方法的特点说明
2014/01/24 Javascript
如何用JavaScript实现动态修改CSS样式表
2016/05/20 Javascript
所见即所得的富文本编辑器bootstrap-wysiwyg使用方法详解
2016/05/27 Javascript
JavaScript中浅讲ajax图文详解
2016/11/11 Javascript
jquery网页日历显示控件calendar3.1使用详解
2016/11/24 Javascript
jquery hover 不停闪动问题的解决方法(亦为stop()的使用)
2017/02/10 Javascript
vue计算属性时v-for处理数组时遇到的一个bug问题
2018/01/21 Javascript
Vue.js做select下拉列表的实例(ul-li标签仿select标签)
2018/03/02 Javascript
用ES6的class模仿Vue写一个双向绑定的示例代码
2018/04/20 Javascript
Vue登录注册并保持登录状态的方法
2018/08/17 Javascript
vue组件表单数据回显验证及提交的实例代码
2018/08/30 Javascript
Vue+Element实现网页版个人简历系统(推荐)
2019/12/31 Javascript
2019最新21个MySQL高频面试题介绍
2020/02/06 Javascript
python海龟绘图实例教程
2014/07/24 Python
shelve  用来持久化任意的Python对象实例代码
2016/10/12 Python
详解利用python+opencv识别图片中的圆形(霍夫变换)
2019/07/01 Python
超简单的Python HTTP服务
2019/07/22 Python
Python 常用日期处理 -- calendar 与 dateutil 模块的使用
2020/09/02 Python
css3 border旋转时的动画应用
2016/01/22 HTML / CSS
基于HTML5陀螺仪实现ofo首页眼睛移动效果的示例
2017/07/31 HTML / CSS
求职简历中的自我评价分享
2013/12/08 职场文书
厂长助理岗位职责
2013/12/27 职场文书
班级标语大全
2014/06/21 职场文书
2014年业务员工作总结范文
2014/11/17 职场文书
教你部署vue项目到docker
2022/04/05 Vue.js
Spring Data JPA框架的核心概念和Repository接口
2022/04/28 Java/Android