通过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 相关文章推荐
跟老齐学Python之不要红头文件(2)
Sep 28 Python
深入浅析Python字符编码
Nov 12 Python
详解python发送各类邮件的主要方法
Dec 22 Python
python3之模块psutil系统性能信息使用
May 30 Python
python 实现图片旋转 上下左右 180度旋转的示例
Jan 24 Python
Django admin model 汉化显示文字的实现方法
Aug 12 Python
详细整理python 字符串(str)与列表(list)以及数组(array)之间的转换方法
Aug 30 Python
Python字符串的修改方法实例
Dec 19 Python
python实现批量修改文件名
Mar 23 Python
浅谈keras中的batch_dot,dot方法和TensorFlow的matmul
Jun 18 Python
Pycharm中如何关掉python console
Oct 27 Python
Python OpenCV之常用滤波器使用详解
Apr 07 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
php数组添加元素方法小结
2014/12/20 PHP
jQuery+PHP实现图片上传并提交功能
2020/07/27 PHP
javascript 隐藏/显示指定的区域附HTML元素【legend】用法
2010/03/05 Javascript
EXTJS FORM HIDDEN TEXTFIELD 赋值 使用value不好用的问题
2011/04/16 Javascript
Jquery实现简单的动画效果代码
2012/03/18 Javascript
用js调用迅雷下载代码的二种方法
2013/04/15 Javascript
JS模拟并美化的表单控件完整实例
2015/08/19 Javascript
vue.js的提示组件
2017/03/02 Javascript
vue2.0 elementUI制作面包屑导航栏
2018/02/22 Javascript
vuex 项目结构目录及一些简单配置介绍
2018/04/08 Javascript
微信小程序将字符串生成二维码图片的操作方法
2018/07/17 Javascript
JS实现简单省市二级联动
2019/11/27 Javascript
解决echarts数据二次渲染不成功的问题
2020/07/20 Javascript
详谈Vue.js框架下main.js,App.vue,page/index.vue之间的区别
2020/08/12 Javascript
Vue+element-ui添加自定义右键菜单的方法示例
2020/12/08 Vue.js
[59:42]Secret vs Alliacne 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
Python如何通过subprocess调用adb命令详解
2017/08/27 Python
Python中xrange与yield的用法实例分析
2017/12/26 Python
python中的闭包函数
2018/02/09 Python
python2 与 pyhton3的输入语句写法小结
2018/09/10 Python
对python3 Serial 串口助手的接收读取数据方法详解
2019/06/12 Python
python获取地震信息 微信实时推送
2019/06/18 Python
python爬虫爬取幽默笑话网站
2019/10/24 Python
学会迭代器设计模式,帮你大幅提升python性能
2021/01/03 Python
Python绘制K线图之可视化神器pyecharts的使用
2021/03/02 Python
整理的15个非常有用的 HTML5 开发教程和速查手册
2011/10/18 HTML / CSS
使用HTML5的表单验证的简单示例
2015/09/09 HTML / CSS
JavaScript实现前端网页版倒计时
2021/03/24 Javascript
金融专业个人求职信
2013/09/22 职场文书
高中生自我鉴定范文
2013/10/30 职场文书
高一英语教学反思
2014/01/22 职场文书
房地产公司见习自我鉴定
2014/04/28 职场文书
高中升旗仪式演讲稿
2014/09/09 职场文书
出纳岗位职责
2015/01/31 职场文书
保护校园环境倡议书
2015/04/28 职场文书
立项申请报告范本
2015/05/15 职场文书