爬虫辅助相关

 一、代理池

1 代理池的概念

去免费代理网站爬代理数据(ip、端口、代理类型(免费)),放到数据库
用python的web框架搭建一个代理池服务,建一个接口,每次朝服务端发请求,随机从数据库拿出一条代理
代理池服务跟主爬虫程序不相关,是一个独立的服务

2 问题

构建一个代理IP池,可能有下面这些问题:

* 代理IP从何而来?
许多刚接触爬虫的,都试过去西刺、快代理之类有免费代理的网站去抓些免费代理,还是有一些代理能用。当然,如果你有更好的代理接口也可以自己接入。
免费代理的采集也很简单,无非就是:`访问页面`` —> `正则/xpath提取` —> `保存`

* 如何保证代理质量?
可以肯定免费的代理IP大部分都是不能用的,不然别人还提供付费接口干嘛(不过事实上很多代理商的付费IP也不稳定,也有很多是不能用)。
所以采集回来的代理IP不能直接使用,检测的办法也很简单:可以写个程序不断的用代理访问一个稳定的网站,看是否可以正常访问即可。
这个过程可以使用多线/进程或异步的方式,因为检测代理是个很慢的过程。

* 采集回来的代理如何存储?
这里不得不推荐一个国人开发的高性能支持多种数据结构的NoSQL数据库[SSDB](http://ssdb.io/docs/zh_cn/),用于替代Redis。
支持队列、hash、set、k-v对,支持T级别数据。是做分布式爬虫很好中间存储工具。

* 如何让爬虫更方便的用到这些代理?
答案肯定是做成服务咯,Python有这么多的web框架,随便拿一个来写个api供爬虫调用。这样代理和爬虫架构分离有很多好处,
比如:当爬虫完全不用考虑如何校验代理,如何保证拿到的代理可用,这些都由代理池来完成。这样只需要安静的码爬虫代码就行啦。

3 代理池设计

代理池由四部分组成:

* ProxyGetter:
代理获取接口,找几个免费代理源,每调用一次就会抓取几个网站的最新代理放入DB,支持自定义扩展额外的代理获取接口;

* DB:
用于存放代理IP,SSDB或Redis(推荐SSDB)。
[安装参考](https://github.com/jhao104/memory-notes/blob/master/SSDB/SSDB%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE%E8%AE%B0%E5%BD%95.md)

* Schedule:
计划任务,用的APScheduler模块,定时去检测DB中的代理可用性,删除不可用的代理。同时也会主动通过ProxyGetter去获取最新代理放入DB;

* ProxyApi:
代理池的外部接口,由django或flask实现,功能是给爬虫提供与代理池交互的接口;

4 第三方代理池

爬虫代理IP池项目,主要功能为定时采集网上发布的免费代理验证入库,定时验证入库的代理保证代理的可用性,提供API和CLI两种使用方式。
同时你也可以扩展代理源以增加代理池IP的质量和数量。

下载代码
git clone git@github.com:jhao104/proxy_pool.git
或者 https://github.com/jhao104/proxy_pool/releases 下载zip文件

安装依赖
pip install -r requirements.txt

更新配置
# setting.py 为项目配置文件

# 配置API服务
HOST = "0.0.0.0"  # IP
PORT = 5000       # 监听端口

# 配置数据库
DB_CONN = 'redis://:pwd@127.0.0.1:6379/0'

# 配置 ProxyFetcher

PROXY_FETCHER = [
    "freeProxy01",      # 这里是启用的代理抓取方法名,所有fetch方法位于fetcher/proxyFetcher.py
    "freeProxy02",
    # ....
]

# 如果已经具备运行条件, 可用通过proxyPool.py启动。
# 程序分为: schedule 调度程序 和 server Api服务

# 启动调度程序(开始到各个免费代理网站爬取代理数据,会先进行验证,有用的筛选出来)
python proxyPool.py schedule

# 启动webApi服务
python proxyPool.py server

# 朝服务端口发get请求,随机获取一个代理,用json()解析出来
requests.get("http://127.0.0.1:5000/get/").json()
# 删除一个代理
requests.get("http://127.0.0.1:5000/delete/?proxy={}".format(proxy))

源码 https://github.com/jhao104/proxy_pool#readme

4 自己建代理池服务

 

二、cookie池

cookie池搭建流程:
1、selenium写一套模拟登录脚本(需要一堆小号),跑起脚本,自动登录(验证码简单的),手动参与(验证复杂的)
2、拿到cookie,放到redis中
3、python的web框架搭建一个服务,写个接口:127.0.0.0:6000/get/,随机返回一个cookie
4、拿到cookie后,requests可以带着cookie发送请求爬数据,如果cookie失效从redis中剔除

 

三、破解验证码

1 验证码破解
方案一:
用代码去破解,需要会图像识别和处理,像12306这种用图像处理不了;
简单的数字加字母这种可以用代码破解,python有图像处理库,但复杂度高,一般不用来做破解;
不要浪费时间用代码破解,可以手动登录获取cookie,要么用打码平台    

方案二:
专业打码平台,破解验证码(收费),它的图像识别也不是代码实现,而是人在后面点
# 申请超级鹰,注册
# 登录,下载sdk(代码如下),填入用户名密码,软件id


# 注意:很多网站的验证码改成了滑动认证,就很难破解了
# 不用自动登录,自己手动登录进去,拿到cookie,放到redis中,搭个cookie池,每次登录随机拿一个cookie去用
超级鹰sdk
 import requests
from hashlib import md5

class Chaojiying_Client():
    def __init__(self, username, password, soft_id):
        self.username = username
        password =  password.encode('utf8')
        self.password = md5(password).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }

    def PostPic(self, im, codetype):
        """
        im:         # 图片字节
        codetype:   # 题目类型 参考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
        return r.json()

    def ReportError(self, im_id):
        """
        im_id:报错题目的图片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()


if __name__ == '__main__':
    # 实例化传入三个参数,超级鹰用户名、密码、软件ID
    # 用户中心>>软件ID 生成一个 
    chaojiying = Chaojiying_Client('306334678', 'lqz12345', '903641')    
    # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    # 需要从登录的网站扣取验证码图片,发给超级鹰识别
    im = open('a.jpg', 'rb').read()        
    # 1902 验证码类型  官方网站>>价格体系 
    print(chaojiying.PostPic(im, 1902))    

 

四、抓包工具

一般爬取web端数据,就用浏览器调试模式,也可以用抓包工具;爬取移动端数据,需要用抓包工具,抓包工具还用于移动端的测试

抓移动端的包,前提是手机和电脑主机要同一个网络。给手机配置代理,代理服务器主机名设为 PC 的 IP ,代理服务器端口设为 Fiddler上配置的端口 8888
手机通过代理发出的http请求的包都会经过电脑主机,配上抓包工具就能抓取,app也是http请求,但大多数返回的数据都加密

常用抓包工具
mac上一般用charles 
windows上一般用fiddler
[fiddler配置和教程](https://www.cnblogs.com/woaixuexi9999/p/9247705.html)

js逆向和安卓逆向
1、web端反爬措施,用js生成加密串(比如把post请求提交的data生成加密串),抓包后需要逆向破解-->爬取js,但现在很多js混淆、js压缩,要逆向js比较难

2、因为手机和web是共用的接口,加密方法web有一套,移动端也有一套,破解移动端的加密比网站简单一点
使用安卓“改之理”打开app,里面是用jave写的代码,定位到加密方法-->扣出加密方法,用python重写加密方法生成加密串
python调用js函数
 PyExecJS模块,依赖Node-js环境运行

一、简单使用
# js文件:my_js.js
function sum(a,b) {
    return a + b
}

# python文件执行js代码
 with open('my_js.js', 'rt', encoding='utf-8') as f:
      etx = execjs.compile(f.read())   # 拿到js函数
      ret = etx.call('sum', 4, 5)      # 传入函数名, 参数--->执行js函数
      print(ret)  ===> 9
 

二、如果js代码是从浏览器扣出来的,直接执行js代码会报错,因为浏览器环境会有document、window对象,Node-js运行环境只有引擎
# 1 需要一个依赖Node-js的库来模拟浏览器环境:注意,是Node-js环境下载,不是python环境,npm install jsdom
# 2 在js文件中,在拷贝过来的js函数代码上方要加上以下一段代码:
```
const jsdom = require('jsdom');
const {JSDOM} = 'jsdom';
const dom = new JSDOM('<!DOCTYPE html><p>Hello world</p>');
window = dom.window;
document = window.document;
XMLHttpRequest; = window.XMLHttpRequest;
atob = window.atob;
```
# 3 安装完jsdom,会有一个node_modules, cwd指定该环境
 with open('my_js.js', 'rt', encoding='utf-8') as f:
      etx = execjs.compile(f.read(), cwd='node_modules')   
      ret = etx.call('sum', 4, 5)     
posted @ 2022-09-30 12:48  不会钓鱼的猫  阅读(68)  评论(0编辑  收藏  举报