第七天,反爬

 

 
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):
    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和密钥
 
posted @ 2018-09-28 15:30  坚强的小蚂蚁  阅读(226)  评论(0编辑  收藏  举报