通过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 12306抢火车票脚本
Feb 07 Python
Python实现的当前时间多加一天、一小时、一分钟操作示例
May 21 Python
python 同时运行多个程序的实例
Jan 07 Python
Python中常用的内置方法
Jan 28 Python
python3实现指定目录下文件sha256及文件大小统计
Feb 25 Python
python如何制作缩略图
Apr 30 Python
python如何实现不用装饰器实现登陆器小程序
Dec 14 Python
pytorch的梯度计算以及backward方法详解
Jan 10 Python
检测tensorflow是否使用gpu进行计算的方式
Feb 03 Python
在keras里面实现计算f1-score的代码
Jun 15 Python
Python使用xlrd实现读取合并单元格
Jul 09 Python
python中翻译功能translate模块实现方法
Dec 17 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命名空间(namespace)的动态访问及使用技巧
2014/08/18 PHP
为百度UE编辑器上传图片添加水印功能
2015/04/16 PHP
WordPress后台中实现图片上传功能的实例讲解
2016/01/11 PHP
PHP中OpenSSL加密问题整理
2017/12/14 PHP
PHP实现微信小程序用户授权的工具类示例
2019/03/05 PHP
关于__defineGetter__ 和__defineSetter__的说明
2007/05/12 Javascript
判断JavaScript对象是否可用的最正确方法分析
2008/10/03 Javascript
javascript 模式设计之工厂模式学习心得
2010/04/27 Javascript
jquery选择器(常用选择器说明)
2010/09/28 Javascript
addEventListener和attachEvent二者绑定的执行函数中的this不相同
2012/12/09 Javascript
IE6下opacity与JQuery的奇妙结合
2013/03/01 Javascript
button没写type=button会导致点击时提交
2014/03/06 Javascript
JavaScript判断手机号运营商是移动、联通、电信还是其他(代码简单)
2015/09/25 Javascript
jquery解析XML及获取XML节点名称的实现代码
2016/05/18 Javascript
JS解析url查询参数的简单代码
2017/08/06 Javascript
浅谈gulp创建完整的项目流程
2017/12/20 Javascript
Three.js实现3D机房效果
2018/12/30 Javascript
ES6 对象的新功能与解构赋值介绍
2019/02/05 Javascript
[32:47]完美世界DOTA2联赛 GXR vs IO 第二场 11.07
2020/11/09 DOTA
简单介绍Python中的try和finally和with方法
2015/05/05 Python
Python实现Windows上气泡提醒效果的方法
2015/06/03 Python
python:pandas合并csv文件的方法(图书数据集成)
2018/04/12 Python
Flask框架web开发之零基础入门
2018/12/10 Python
python将excel转换为csv的代码方法总结
2019/07/03 Python
python实现连续变量最优分箱详解--CART算法
2019/11/22 Python
Python dict和defaultdict使用实例解析
2020/03/12 Python
Python+OpenCV图像处理——实现直线检测
2020/10/23 Python
HTML5 embed 标签使用方法介绍
2013/08/13 HTML / CSS
绩效管理实施方案
2014/03/19 职场文书
校园文明倡议书
2014/05/16 职场文书
工商管理专业毕业生自我鉴定2014
2014/10/04 职场文书
2015年工程部工作总结
2015/04/30 职场文书
2015年教师国培感言
2015/08/01 职场文书
2019年妇科护士的自我鉴定(3篇)
2019/09/26 职场文书
MySQL里面的子查询的基本使用
2021/08/02 MySQL
MYSQL常用函数介绍
2022/05/05 MySQL