通过Python爬虫代理IP快速增加博客阅读量


Posted in Python onDecember 14, 2016

写在前面

题目所说的并不是目的,主要是为了更详细的了解网站的反爬机制,如果真的想要提高博客的阅读量,优质的内容必不可少。

了解网站的反爬机制

一般网站从以下几个方面反爬虫:

1. 通过Headers反爬虫

从用户请求的Headers反爬虫是最常见的反爬虫策略。很多网站都会对Headers的User-Agent进行检测,还有一部分网站会对Referer进行检测(一些资源网站的防盗链就是检测Referer)。

如果遇到了这类反爬虫机制,可以直接在爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值修改为目标网站域名。对于检测Headers的反爬虫,在爬虫中修改或者添加Headers就能很好的绕过。

2. 基于用户行为反爬虫

还有一部分网站是通过检测用户行为,例如同一IP短时间内多次访问同一页面,或者同一账户短时间内多次进行相同操作。

大多数网站都是前一种情况,对于这种情况,使用IP代理就可以解决。我们可以将代理IP检测之后保存在文件当中,但这种方法并不可取,代理IP失效的可能性很高,因此从专门的代理IP网站实时抓取,是个不错的选择。

对于第二种情况,可以在每次请求后随机间隔几秒再进行下一次请求。有些有逻辑漏洞的网站,可以通过请求几次,退出登录,重新登录,继续请求来绕过同一账号短时间内不能多次进行相同请求的限制。

还有针对cookies,通过检查cookies来判断用户是否是有效用户,需要登录的网站常采用这种技术。更深入一点的还有,某些网站的登录会动态更新验证,如推酷登录时,会随机分配用于登录验证的authenticity_token,authenticity_token会和用户提交的登录名和密码一起发送回服务器。

3. 基于动态页面的反爬虫

有的时候将目标页面抓取下来,发现关键的信息内容空白一片,只有框架代码,这是因为该网站的信息是通过用户Post的XHR动态返回内容信息,解决这种问题的方法就是通过开发者工具(FireBug等)对网站流进行分析,找到单独的内容信息request(如Json),对内容信息进行抓取,获取所需内容。

更复杂一点的还有对动态请求加密的,参数无法解析,也就无法进行抓取。这种情况下,可以通过Mechanize,selenium RC,调用浏览器内核,就像真实使用浏览器上网那样抓取,可以最大限度的抓取成功,只不过效率上会打些折扣。笔者测试过,用urllib抓取拉勾网招聘信息30页所需时间为三十多秒,而用模拟浏览器内核抓取需要2——3分钟。

4. 限定某些IP访问

免费的代理IP可以从很多网站获取到,既然爬虫可以利用这些代理IP进行网站抓取,网站也可以利用这些代理IP反向限制,通过抓取这些IP保存在服务器上来限制利用代理IP进行抓取的爬虫。

进入正题

好了,现在实际操作一下,编写一个通过代理IP访问网站的爬虫。

首先获取代理IP,用来抓取。

def Get_proxy_ip():
 headers = {
 'Host': 'www.xicidaili.com',
 'User-Agent':'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
 'Accept': r'application/json, text/javascript, */*; q=0.01',
 'Referer': r'http://www.xicidaili.com/', 
 }
 req = request.Request(r'http://www.xicidaili.com/nn/', headers=headers) #发布代理IP的网站
 response = request.urlopen(req)
 html = response.read().decode('utf-8')
 proxy_list = []
 ip_list = re.findall(r'\d+\.\d+\.\d+\.\d+',html)
 port_list = re.findall(r'<td>\d+</td>',html)
 for i in range(len(ip_list)):
 ip = ip_list[i]
 port = re.sub(r'<td>|</td>', '', port_list[i])
 proxy = '%s:%s' %(ip,port)
 proxy_list.append(proxy)
 return proxy_list

顺带一提,有些网站会通过检查代理IP的真实IP来限制爬虫抓取。这里就要稍微提一下代理IP的知识。

代理IP里的“透明”“匿名”“高匿”分别是指?

透明代理的意思是客户端根本不需要知道有代理服务器的存在,但是它传送的仍然是真实的IP。使用透明IP,就无法绕过通过一定时间内IP访问次数的限制。

普通匿名代理能隐藏客户机的真实IP,但会改变我们的请求信息,服务器端有可能会认为我们使用了代理。不过使用此种代理时,虽然被访问的网站不能知道你的ip地址,但仍然可以知道你在使用代理,这样的IP就会被网站禁止访问。

高匿名代理不改变客户机的请求,这样在服务器看来就像有个真正的客户浏览器在访问它,这时客户的真实IP是隐藏的,网站就不会认为我们使用了代理。

综上所述,爬虫代理IP最好使用“高匿IP”

user_agent_list包含了目前主流浏览器请求的RequestHeaders的user-agent,通过它我们可以模仿各类浏览器的请求。

user_agent_list = [
 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
  'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3',
 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)',
 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
 'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
 'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11',
 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)',
 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0',
 'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
]

通过设定随机等待时间来访问网站,可以绕过某些网站对于请求间隔的限制。

def Proxy_read(proxy_list, user_agent_list, i):
 proxy_ip = proxy_list[i]
 print('当前代理ip:%s'%proxy_ip)
 user_agent = random.choice(user_agent_list)
 print('当前代理user_agent:%s'%user_agent)
 sleep_time = random.randint(1,3)
 print('等待时间:%s s' %sleep_time)
 time.sleep(sleep_time) #设置随机等待时间
 print('开始获取')
 headers = {
 'Host': 's9-im-notify.csdn.net',
 'Origin':'http://blog.csdn.net',
 'User-Agent': user_agent,
 'Accept': r'application/json, text/javascript, */*; q=0.01',
 'Referer': r'http://blog.csdn.net/u010620031/article/details/51068703',
 }
 proxy_support = request.ProxyHandler({'http':proxy_ip})
 opener = request.build_opener(proxy_support)
 request.install_opener(opener)
 req = request.Request(r'http://blog.csdn.net/u010620031/article/details/51068703',headers=headers)
 try:
 html = request.urlopen(req).read().decode('utf-8')
 except Exception as e:
 print('******打开失败!******')
 else:
 global count
 count +=1
 print('OK!总计成功%s次!'%count)

以上就是爬虫使用代理的相关知识点,虽然还很浅显,但大部分场景是可以应付的了的。

附上源码

#! /usr/bin/env python3
from urllib import request
import random
import time
import lxml
import re
user_agent_list = [
 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
  'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3',
 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)',
 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
 'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
 'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11',
 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)',
 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0',
 'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
]
count = 0
def Get_proxy_ip():
 headers = {
 'Host': 'www.xicidaili.com',
 'User-Agent':'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
 'Accept': r'application/json, text/javascript, */*; q=0.01',
 'Referer': r'http://www.xicidaili.com/',
 }
 req = request.Request(r'http://www.xicidaili.com/nn/', headers=headers)
 response = request.urlopen(req)
 html = response.read().decode('utf-8')
 proxy_list = []
 ip_list = re.findall(r'\d+\.\d+\.\d+\.\d+',html)
 port_list = re.findall(r'<td>\d+</td>',html)
 for i in range(len(ip_list)):
 ip = ip_list[i]
 port = re.sub(r'<td>|</td>', '', port_list[i])
 proxy = '%s:%s' %(ip,port)
 proxy_list.append(proxy)
 return proxy_list
def Proxy_read(proxy_list, user_agent_list, i):
 proxy_ip = proxy_list[i]
 print('当前代理ip:%s'%proxy_ip)
 user_agent = random.choice(user_agent_list)
 print('当前代理user_agent:%s'%user_agent)
 sleep_time = random.randint(1,3)
 print('等待时间:%s s' %sleep_time)
 time.sleep(sleep_time)
 print('开始获取')
 headers = {
 'Host': 's9-im-notify.csdn.net',
 'Origin':'http://blog.csdn.net',
 'User-Agent': user_agent,
 'Accept': r'application/json, text/javascript, */*; q=0.01',
 'Referer': r'http://blog.csdn.net/u010620031/article/details/51068703',
 }
 proxy_support = request.ProxyHandler({'http':proxy_ip})
 opener = request.build_opener(proxy_support)
 request.install_opener(opener)
 req = request.Request(r'http://blog.csdn.net/u010620031/article/details/51068703',headers=headers)
 try:
 html = request.urlopen(req).read().decode('utf-8')
 except Exception as e:
 print('******打开失败!******')
 else:
 global count
 count +=1
 print('OK!总计成功%s次!'%count)
if __name__ == '__main__':
 proxy_list = Get_proxy_ip()
 for i in range(100):
 Proxy_read(proxy_list, user_agent_list, i)

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Python 相关文章推荐
轻量级的Web框架Flask 中模块化应用的实现
Sep 11 Python
Python多进程fork()函数详解
Feb 22 Python
python实现QQ空间自动点赞功能
Apr 09 Python
redis数据库及与python交互用法简单示例
Nov 01 Python
python找出列表中大于某个阈值的数据段示例
Nov 24 Python
Python Numpy 自然数填充数组的实现
Nov 28 Python
python 实现线程之间的通信示例
Feb 14 Python
Tensorflow中的降维函数tf.reduce_*使用总结
Apr 20 Python
Python collections.defaultdict模块用法详解
Jun 18 Python
Python2及Python3如何实现兼容切换
Sep 01 Python
python开发入门——set的使用
Sep 03 Python
Python 多进程、多线程效率对比
Nov 19 Python
Python实现并行抓取整站40万条房价数据(可更换抓取城市)
Dec 14 #Python
从零开始学Python第八周:详解网络编程基础(socket)
Dec 14 #Python
Python 'takes exactly 1 argument (2 given)' Python error
Dec 13 #Python
请不要重复犯我在学习Python和Linux系统上的错误
Dec 12 #Python
Python 包含汉字的文件读写之每行末尾加上特定字符
Dec 12 #Python
详解python3百度指数抓取实例
Dec 12 #Python
python实现多线程抓取知乎用户
Dec 12 #Python
You might like
基于MySQL到MongoDB简易对照表的详解
2013/06/03 PHP
Thinkphp 框架扩展之数据库驱动常用方法小结
2020/04/23 PHP
基于ThinkPHP删除目录及目录文件函数
2020/10/28 PHP
JTrackBar水平拖动效果
2007/07/15 Javascript
再说AutoComplete自动补全之实现原理
2011/11/05 Javascript
Bootstrap CSS布局之按钮
2016/12/17 Javascript
Javascript实现从小到大的数组转换成二叉搜索树
2017/06/13 Javascript
js实现canvas图片与img图片的相互转换的示例
2017/08/31 Javascript
React组件中的this的具体使用
2018/02/28 Javascript
vue addRoutes实现动态权限路由菜单的示例
2018/05/15 Javascript
用node开发并发布一个cli工具的方法步骤
2019/01/03 Javascript
JavaScript数据结构之栈实例用法
2019/01/18 Javascript
JavaScript中this的全面解析及常见实例
2019/05/14 Javascript
jQuery实现弹出层效果
2019/12/10 jQuery
[01:57]2018DOTA2亚洲邀请赛赛前采访-iG
2018/04/03 DOTA
python代码检查工具pylint 让你的python更规范
2012/09/05 Python
Python将多个excel表格合并为一个表格
2021/02/22 Python
tensorflow建立一个简单的神经网络的方法
2018/02/10 Python
python如何修改装饰器中参数
2018/03/20 Python
Python将DataFrame的某一列作为index的方法
2018/04/08 Python
python numpy数组的索引和切片的操作方法
2018/10/20 Python
Python socket模块实现的udp通信功能示例
2019/04/10 Python
django如何实现视图重定向
2019/07/24 Python
Tensorflow不支持AVX2指令集的解决方法
2020/02/03 Python
Tensorflow限制CPU个数实例
2020/02/06 Python
基于 Python 实践感知器分类算法
2021/01/07 Python
Belvilla德国:在线预订度假屋
2018/04/10 全球购物
爱奇艺VIP会员:大剧抢先看
2018/07/11 全球购物
Omio荷兰:预订火车、巴士和机票
2018/11/04 全球购物
Web Service面试题:如何搭建Axis2的开发环境
2012/06/20 面试题
高中生自我鉴定范文
2013/10/30 职场文书
资产评估专业学生的自我鉴定
2013/11/14 职场文书
学校就业推荐信范文
2014/05/19 职场文书
2014村书记党建工作汇报材料
2014/11/02 职场文书
制定企业培训计划的五大要点!
2019/07/10 职场文书
Java比较两个对象中全部属性值是否相等的方法
2021/08/07 Java/Android