第七天,反爬
DOWNLOAD_DELAY: 同一网站下个页面下载延迟时间
一. 爬虫和反爬虫的斗争
小技巧:
1. 在网页中右键查看源码和用F12查看是有区别的
如果网页中大量使用ajax来加载数据,那么右键查看源码的方式只能看到ajax加载前的信息,F12看到的是ajax加载后的信息,我们一般用爬虫爬取的都是ajax加载前的信息
2. 在有些网站会检测出scrapy的cookie值,因此要禁用cookie,需要在settings.py文件中执行COOKIES_ENABLED = False,默认为True
注意
1)这个禁用的只是scrapy自己的cookie而不是在spider文件中自定义的
2)只有在setting中禁用自身框架cookie,才能在spider文件中使用自定义的cookie
二. scrapy架构图
1. spiders.py文件发送一个URL请求到ENGINE
2. ENGINE直接把URL请求发送到SCHEDULER
3. SCHEDULER把原先的URL请求处理后,自己生成一个请求发送到ENGINE
4. ENGINE拿到这个请求后,通过downloadermiddleware进行处理后发送给DOWNLOADER
5. DOWNLOADER把请求处理后,通过MIDDLEWARE把响应内容发送给ENGINE
6. ENGINE把响应内容传给spiders.py文件
7. spiders.py文件通过解析响应内容,通过spider middleware判断是item还是requests,然后发送给ENGINE
8. 如果是item,就转发给ITEMPIPELINES,如果是请求就转发给SCHEDULER
源码可在python安装目录中的site-packages/scrapy/core中找到
三. Request和Response
源代码在scrapy/http目录下
还以伯乐在线具体例子看下request和response的使用方法
Response类中初始函数的参数request就是yield Request的返回值
四. 随机切换User-agent
我们的浏览器其实就是一个user-agent,它是用来标记是通过什么方式访问服务器资源的
如果不加user-agent,那么默认是用python字符串作为user-agent
1. 可以使用github里搜索fake-useragent,使用方法如下
pip install fake-useragent
from fake_useragent import UserAgent
ub = UserAgent()
>>> ub.ie
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; FunWebProducts)'
>>>ub.firefox
'Mozilla/5.0 (X11; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0'
>>> ub.random
'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2117.157 Safari/537.36'
官方网址
所有user-agent
2. scrapy中的使用方法
1)在middlewares.py中定义
上面最后一行header后面要加s
2)其实我们可以自己定制选取哪种代理,是IE,chrome还是firefox
在settings.py中定义
修改RandomUserAgentMiddleware
说明
getattr() 函数用于返回一个对象属性值。参考http://www.runoob.com/python/python-func-getattr.html
3)然后修改settings.py中
五. IP代理池
查看本机IP地址:直接百度输入本机IP
西刺找到高匿代理
使用代理方法,只需要在middlewares.py中的Process_request函数后面加一行代码
方法2:自己另外写一个代理池
其中GetIP为tool包里自定义的爬取文件里的类
方法3,scrapy有一个收费的插件
github上搜索scrapy-plugins/scrapy-crawlera
2. 使用tor浏览器来包装ip,达到匿名ip的作用,但是需要VPN下载
六. 验证码识别
在线自动打码平台:云打码,下面代码的前提:需要先把验证码截图保存后再处理
# -*- coding: utf-8 -*-
__author__ = 'bobby'
import json
import requests
class YDMHttp(object):
apiurl = 'http://api.yundama.com/api.php'
username = ''
password = ''
appid = ''
appkey = ''
def __init__(self, username, password, appid, appkey):
self.username = username
self.password = password
self.appid = str(appid)
self.appkey = appkey
def balance(self):
data = {'method': 'balance', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey}
response_data = requests.post(self.apiurl, data=data)
ret_data = json.loads(response_data.text)
if ret_data["ret"] == 0:
print ("获取剩余积分", ret_data["balance"])
return ret_data["balance"]
else:
return None
def login(self):
data = {'method': 'login', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey}
response_data = requests.post(self.apiurl, data=data)
ret_data = json.loads(response_data.text)
if ret_data["ret"] == 0:
print ("登录成功", ret_data["uid"])
return ret_data["uid"]
else:
return None
def decode(self, filename, codetype, timeout):
data = {'method': 'upload', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'codetype': str(codetype), 'timeout': str(timeout)}
files = {'file': open(filename, 'rb')}
response_data = requests.post(self.apiurl, files=files, data=data)
ret_data = json.loads(response_data.text)
if ret_data["ret"] == 0:
print ("识别成功", ret_data["text"])
return ret_data["text"]
else:
return None
def ydm(file_path):
username = 'da_ge_da1'
# 密码
password = 'da_ge_da'
# 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得!
appid = 3129
# 软件密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!
appkey = '40d5ad41c047179fc797631e3b9c3025'
# 图片文件
filename = 'image/captcha.jpg'
# 验证码类型,# 例:1004表示4位字母数字,不同类型收费不同。请准确填写,否则影响识别率。在此查询所有类型 http://www.yundama.com/price.html
codetype = 5000
# 超时时间,秒
timeout = 60
# 检查
yundama = YDMHttp(username, password, appid, appkey)
if (username == 'username'):
print('请设置好相关参数再测试')
else:
# 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
return yundama.decode(file_path, codetype, timeout);
if __name__ == "__main__":
# 用户名
username = 'da_ge_da1'
# 密码
password = 'da_ge_da'
# 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得!
appid = 3129
# 软件密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!
appkey = '40d5ad41c047179fc797631e3b9c3025'
# 图片文件
filename = 'image/captcha.jpg'
# 验证码类型,# 例:1004表示4位字母数字,不同类型收费不同。请准确填写,否则影响识别率。在此查询所有类型 http://www.yundama.com/price.html
codetype = 5000
# 超时时间,秒
timeout = 60
# 检查
if (username == 'username'):
print ('请设置好相关参数再测试')
else:
# 初始化
yundama = YDMHttp(username, password, appid, appkey)
# 登陆云打码
uid = yundama.login();
print('uid: %s' % uid)
# 登陆云打码
uid = yundama.login();
print ('uid: %s' % uid)
# 查询余额
balance = yundama.balance();
print ('balance: %s' % balance)
# 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
text = yundama.decode(filename, codetype, timeout);
代码中函数ydm中的username和password分别是普通用户的账户和密码
软件ID和软件密钥是开发者账号登陆后,自己设置的,只需要填写一个软件名就可自动生成软件ID和密钥
努力生活,融于自然