回顾
scrapy框架
-
五大组件+工作流程+常用命令
x
1【1】五大组件
21.1) 引擎(Engine)
31.2) 爬虫程序(Spider)
41.3) 调度器(Scheduler)
51.4) 下载器(Downloader)
61.5) 管道文件(Pipeline)
71.6) 下载器中间件(Downloader Middlewares)
81.7) 蜘蛛中间件(Spider Middlewares)
910【2】工作流程
112.1) Engine向Spider索要URL,交给Scheduler入队列
122.2) Scheduler处理后出队列,通过Downloader Middlewares交给Downloader去下载
132.3) Downloader得到响应后,通过Spider Middlewares交给Spider
142.4) Spider数据提取:
15a) 数据交给Pipeline处理
16b) 需要跟进URL,继续交给Scheduler入队列,依次循环
1718【3】常用命令
193.1) scrapy startproject 项目名
203.2) scrapy genspider 爬虫名 域名
213.3) scrapy crawl 爬虫名
完成scrapy项目完整流程
-
完整流程
x1【1】scrapy startproject Tencent
2【2】cd Tencent
3【3】scrapy genspider tencent tencent.com
4【4】items.py(定义爬取数据结构)
5import scrapy
6class TencentItem(scrapy.Item):
7name = scrapy.Field()
8address = scrapy.Field()
910【5】tencent.py(写爬虫文件)
11import scrapy
12from ..items import TencentItem
13class TencentSpider(scrapy.Spider):
14name = 'tencent'
15allowed_domains = ['tencent.com']
16start_urls = ['']
17def parse(self, response):
18item = TencentItem()
19item['name'] = xxxx
20yield item
21
22【6】pipelines.py(数据处理)
23class TencentPipeline(object):
24def process_item(self, item, spider):
25return item
2627【7】settings.py(全局配置)
2829【8】run.py
30from scrapy import cmdline
31cmdline.execute('scrapy crawl tencent'.split())
我们必须记住
-
熟练记住
xxxxxxxxxx
231【1】响应对象response属性及方法
21.1) response.text :获取响应内容 - 字符串
31.2) response.body :获取bytes数据类型
41.3) response.xpath('')
51.4) response.xpath('').extract() :提取文本内容,将列表中所有元素序列化为Unicode字符串
61.5) response.xpath('').extract_first() :序列化提取列表中第1个文本内容
71.6) response.xpath('').get() : 提取列表中第1个文本内容(等同于extract_first())
89【2】settings.py中常用变量
102.1) 设置数据导出编码(主要针对于json文件)
11FEED_EXPORT_ENCODING = 'utf-8'
122.2) 设置User-Agent
13USER_AGENT = ''
142.3) 设置最大并发数(默认为16)
15CONCURRENT_REQUESTS = 32
162.4) 下载延迟时间(每隔多长时间请求一个网页)
17DOWNLOAD_DELAY = 0.5
182.5) 请求头
19DEFAULT_REQUEST_HEADERS = {'Cookie' : 'xxx'}
202.6) 添加项目管道
21ITEM_PIPELINES = {'目录名.pipelines.类名' : 优先级}
222.7) cookie(默认禁用,取消注释-True|False都为开启)
23COOKIES_ENABLED = False
爬虫项目启动方式
-
启动方式
xxxxxxxxxx
91【1】方式一:基于start_urls
21.1) 从爬虫文件(spider)的start_urls变量中遍历URL地址交给调度器入队列,
31.2) 把下载器返回的响应对象(response)交给爬虫文件的parse(self,response)函数处理
4
5【2】方式二
6重写start_requests()方法,从此方法中获取URL,交给指定的callback解析函数处理
72.1) 去掉start_urls变量
82.2) def start_requests(self):
9# 生成要爬取的URL地址,利用scrapy.Request()方法交给调度器
2.笔记
瓜子二手车直卖网 - 二级页面
-
目标说明
xxxxxxxxxx
91【1】在抓取一级页面的代码基础上升级
2【2】一级页面所抓取数据(和之前一样):
32.1) 汽车链接
42.2) 汽车名称
52.3) 汽车价格
6【3】二级页面所抓取数据
73.1) 行驶里程: //ul[@class="assort clearfix"]/li[2]/span/text()
83.2) 排量: //ul[@class="assort clearfix"]/li[3]/span/text()
93.3) 变速箱: //ul[@class="assort clearfix"]/li[4]/span/text()
在原有项目基础上实现
-
步骤1 - items.py
xxxxxxxxxx
151# 添加二级页面所需抓取的数据结构
2
3import scrapy
4
5class GuaziItem(scrapy.Item):
6# define the fields for your item here like:
7# 一级页面: 链接、名称、价格
8url = scrapy.Field()
9name = scrapy.Field()
10price = scrapy.Field()
11# 二级页面: 时间、里程、排量、变速箱
12time = scrapy.Field()
13km = scrapy.Field()
14disp = scrapy.Field()
15trans = scrapy.Field()
-
步骤2 - car2.py
xxxxxxxxxx
431"""
2重写start_requests()方法,效率极高
3"""
4# -*- coding: utf-8 -*-
5import scrapy
6from ..items import CarItem
7
8class GuaziSpider(scrapy.Spider):
9# 爬虫名
10name = 'car2'
11# 允许爬取的域名
12allowed_domains = ['www.guazi.com']
13# 1、去掉start_urls变量
14# 2、重写 start_requests() 方法
15def start_requests(self):
16"""生成所有要抓取的URL地址,一次性交给调度器入队列"""
17for i in range(1,6):
18url = 'https://www.guazi.com/bj/buy/o{}/#bread'.format(i)
19# scrapy.Request(): 把请求交给调度器入队列
20yield scrapy.Request(url=url,callback=self.parse)
21
22def parse(self, response):
23# 基准xpath: 匹配所有汽车的节点对象列表
24li_list = response.xpath('//ul[@class="carlist clearfix js-top"]/li')
25# 给items.py中的 GuaziItem类 实例化
26item = CarItem()
27for li in li_list:
28item['url'] = 'https://www.guazi.com' + li.xpath('./a[1]/@href').get()
29item['name'] = li.xpath('./a[1]/@title').get()
30item['price'] = li.xpath('.//div[@class="t-price"]/p/text()').get()
31# Request()中meta参数: 在不同解析函数之间传递数据,item数据会随着response一起返回
32yield scrapy.Request(url=item['url'], meta={'meta_1': item}, callback=self.detail_parse)
33
34def detail_parse(self, response):
35"""汽车详情页的解析函数"""
36# 获取上个解析函数传递过来的 meta 数据
37item = response.meta['meta_1']
38item['km'] = response.xpath('//ul[@class="assort clearfix"]/li[2]/span/text()').get()
39item['disp'] = response.xpath('//ul[@class="assort clearfix"]/li[3]/span/text()').get()
40item['trans'] = response.xpath('//ul[@class="assort clearfix"]/li[4]/span/text()').get()
41
42# 1条数据最终提取全部完成,交给管道文件处理
43yield item
-
步骤3 - pipelines.py
x
1# 将数据存入mongodb数据库,此处我们就不对MySQL表字段进行操作了,如有兴趣可自行完善
2# MongoDB管道
3import pymongo
4
5class GuaziMongoPipeline(object):
6def open_spider(self, spider):
7"""爬虫项目启动时只执行1次,用于连接MongoDB数据库"""
8self.conn = pymongo.MongoClient(MONGO_HOST,MONGO_PORT)
9self.db = self.conn[MONGO_DB]
10self.myset = self.db[MONGO_SET]
11
12def process_item(self,item,spider):
13car_dict = dict(item)
14self.myset.insert_one(car_dict)
1516return item
-
步骤4 - settings.py
xxxxxxxxxx
51# 定义MongoDB相关变量
2MONGO_HOST = 'localhost'
3MONGO_PORT = 27017
4MONGO_DB = 'guazidb'
5MONGO_SET = 'guaziset'
盗墓笔记小说抓取 - 三级页面
-
目标
xxxxxxxxxx
41【1】URL地址 :http://www.daomubiji.com/
2【2】要求 : 抓取目标网站中盗墓笔记所有章节的所有小说的具体内容,保存到本地文件
3./data/novel/盗墓笔记1:七星鲁王宫/七星鲁王_第一章_血尸.txt
4./data/novel/盗墓笔记1:七星鲁王宫/七星鲁王_第二章_五十年后.txt
-
准备工作xpath
xxxxxxxxxx
131【1】一级页面 - 大章节标题、链接:
21.1) 基准xpath匹配a节点对象列表: '//li[contains(@id,"menu-item-20")]/a'
31.2) 大章节标题: './text()'
41.3) 大章节链接: './@href'
56【2】二级页面 - 小章节标题、链接
72.1) 基准xpath匹配article节点对象列表: '//article'
82.2) 小章节标题: './a/text()'
92.3) 小章节链接: './a/@href'
1011【3】三级页面 - 小说内容
123.1) p节点列表: '//article[@class="article-content"]/p/text()'
133.2) 利用join()进行拼接: ' '.join(['p1','p2','p3',''])
项目实现
-
1、创建项目及爬虫文件
xxxxxxxxxx
31scrapy startproject Daomu
2cd Daomu
3scrapy genspider daomu www.daomubiji.com
-
2、定义要爬取的数据结构 - itemspy
xxxxxxxxxx
61class DaomuItem(scrapy.Item):
2# 拷问: 你的pipelines.py中需要处理哪些数据? 文件名、路径
3# 文件名:小标题名称 son_title: 七星鲁王 第一章 血尸
4son_title = scrapy.Field()
5directory = scrapy.Field()
6content = scrapy.Field()
-
3、爬虫文件实现数据抓取 - daomu.py
xxxxxxxxxx
511# -*- coding: utf-8 -*-
2import scrapy
3from ..items import DaomuItem
4import os
5
6class DaomuSpider(scrapy.Spider):
7name = 'daomu'
8allowed_domains = ['www.daomubiji.com']
9start_urls = ['http://www.daomubiji.com/']
10
11def parse(self, response):
12"""一级页面解析函数:提取大标题+大链接,并把大链接交给调度器入队列"""
13a_list = response.xpath('//li[contains(@id,"menu-item-20")]/a')
14for a in a_list:
15item = DaomuItem()
16parent_title = a.xpath('./text()').get()
17parent_url = a.xpath('./@href').get()
18item['directory'] = './novel/{}/'.format(parent_title)
19# 创建对应文件夹
20if not os.path.exists(item['directory']):
21os.makedirs(item['directory'])
22# 交给调度器入队列
23yield scrapy.Request(url=parent_url, meta={'meta_1':item}, callback=self.detail_page)
24
25# 返回了11个response,调用了这个函数
26def detail_page(self, response):
27"""二级页面解析函数:提取小标题、小链接"""
28# 把item接收
29meta_1 = response.meta['meta_1']
30art_list = response.xpath('//article')
31for art in art_list:
32# 只要有继续交往调度器的请求,就必须新建item对象
33item = DaomuItem()
34item['son_title'] = art.xpath('./a/text()').get()
35son_url = art.xpath('./a/@href').get()
36item['directory'] = meta_1['directory']
37# 再次交给调度器入队列
38yield scrapy.Request(url=son_url, meta={'item':item}, callback=self.get_content)
39
40# 盗墓笔记1: 传过来了75个response
41# 盗墓笔记2: 传过来了 n 个response
42# ... ...
43def get_content(self, response):
44"""三级页面解析函数:提取具体小说内容"""
45item = response.meta['item']
46# content_list: ['段落1','段落2','段落3',...]
47content_list = response.xpath('//article[@class="article-content"]/p/text()').extract()
48item['content'] = ' '.join(content_list)
49
50# 至此,一条item数据全部提取完成
51yield item
-
4、管道文件实现数据处理 - pipelines.py
xxxxxxxxxx
81class DaomuPipeline(object):
2def process_item(self, item, spider):
3# filename: ./novel/盗墓笔记1:七星鲁王宫/七星鲁王_第一章_血尸.txt
4filename = '{}{}.txt'.format(item['directory'], item['son_title'].replace(' ', '_'))
5with open(filename, 'w') as f:
6f.write(item['content'])
7
8return item
-
5、全局配置 - setting.py
xxxxxxxxxx
101ROBOTSTXT_OBEY = False
2DOWNLOAD_DELAY = 0.5
3DEFAULT_REQUEST_HEADERS = {
4'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
5'Accept-Language': 'en',
6'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
7}
8ITEM_PIPELINES = {
9'Daomu.pipelines.DaomuPipeline': 300,
10}
Scrapy数据持久化
-
数据持久化 - 数据库
xxxxxxxxxx
151【1】在setting.py中定义相关变量
2【2】pipelines.py中导入settings模块
3def open_spider(self,spider):
4"""爬虫开始执行1次,用于数据库连接"""
56def process_item(self,item,spider):
7"""具体处理数据"""
8return item
910def close_spider(self,spider):
11"""爬虫结束时执行1次,用于断开数据库连接"""
12【3】settings.py中添加此管道
13ITEM_PIPELINES = {'':200}
14
15【注意】 :process_item() 函数中一定要 return item ,当前管道的process_item()的返回值会作为下一个管道 process_item()的参数
-
数据持久化 - csv、json文件
xxxxxxxxxx
81【1】存入csv文件
2scrapy crawl car -o car.csv
34【2】存入json文件
5scrapy crawl car -o car.json
6
7【3】注意: settings.py中设置导出编码 - 主要针对json文件
8FEED_EXPORT_ENCODING = 'utf-8'
腾讯招聘职位数据持久化
-
scrapy项目代码
xxxxxxxxxx
11见day07笔记:Tencent 文件夹
-
建库建表SQL
xxxxxxxxxx
101create database tencentdb charset utf8;
2use tencentdb;
3create table tencenttab(
4job_name varchar(200),
5job_type varchar(200),
6job_duty varchar(2000),
7job_require varchar(2000),
8job_add varchar(100),
9job_time varchar(100)
10)charset=utf8;
-
MySQL数据持久化实现
xxxxxxxxxx
381# 【1】settings.py添加
2ITEM_PIPELINES = {
3# 在原来基础上添加MySQL的管道
4'Tencent.pipelines.TencentMysqlPipeline': 200,
5}
6MYSQL_HOST = '127.0.0.1'
7MYSQL_USER = 'root'
8MYSQL_PWD = '123456'
9MYSQL_DB = 'tencentdb'
10CHARSET = 'utf8'
11
12# 【2】pipelines.py新建MySQL管道类
13from .settings import *
14import pymysql
15
16class TencentMysqlPipeline:
17def open_spider(self, spider):
18self.db = pymysql.connect(MYSQL_HOST, MYSQL_USER, MYSQL_PWD, MYSQL_DB, charset=CHARSET)
19self.cur = self.db.cursor()
20self.ins = 'insert into tencenttab values(%s,%s,%s,%s,%s,%s)'
21
22def process_item(self, item, spider):
23li = [
24item['job_name'],
25item['job_type'],
26item['job_duty'],
27item['job_require'],
28item['job_add'],
29item['job_time'],
30]
31self.cur.execute(self.ins, li)
32self.db.commit()
33
34return item
35
36def close_spider(self, item, spider):
37self.cur.close()
38self.db.close()
-
MongoDB数据持久化实现
xxxxxxxxxx
221# 【1】settings.py中添加
2ITEM_PIPELINES = {
3# 添加MongoDB管道
4'Tencent.pipelines.TencentMongoPipeline': 400,
5}
6MONGO_HOST = '127.0.0.1'
7MONGO_PORT = 27017
8MONGO_DB = 'tencentdb'
9MONGO_SET = 'tencentset'
10
11# 【2】pipelines.py中新建MongoDB管道类
12from .settings import *
13import pymongo
14
15class TencentMongoPipeline:
16def open_spider(self, spider):
17self.conn = pymongo.MongoClient(MONGO_HOST, MONGO_PORT)
18self.db = self.conn[MONGO_DB]
19self.myset = self.db[MONGO_SET]
20
21def process_item(self, item, spider):
22self.myset.insert_one(dict(item))
-
csv及json数据持久化实现
xxxxxxxxxx
61【1】csv
2scrapy crawl tencent -o tencent.csv
34【2】json
5settings.py中添加变量: FEED_EXPORT_ENCODING = 'utf-8'
6scrapy crawl tencent -o tencent.json
分布式爬虫
-
分布式爬虫介绍
xxxxxxxxxx
61【1】原理
2多台主机共享1个爬取队列
34【2】实现
52.1) 重写scrapy调度器(scrapy_redis模块)
62.2) sudo pip3 install scrapy_redis
-
为什么使用redis
xxxxxxxxxx
21【1】Redis基于内存,速度快
2【2】Redis非关系型数据库,Redis中集合,存储每个request的指纹
scrapy_redis详解
-
GitHub地址
xxxxxxxxxx
11https://github.com/rmax/scrapy-redis
-
settings.py说明
xxxxxxxxxx
251# 重新指定调度器: 启用Redis调度存储请求队列
2SCHEDULER = "scrapy_redis.scheduler.Scheduler"
3
4# 重新指定去重机制: 确保所有的爬虫通过Redis去重
5DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
6
7# 不清除Redis队列: 暂停/恢复/断点续爬(默认清除为False,设置为True不清除)
8SCHEDULER_PERSIST = True
9
10# 优先级队列 (默认)
11SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'
12#可选用的其它队列
13# 先进先出
14SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.FifoQueue'
15# 后进先出
16SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.LifoQueue'
17
18# redis管道
19ITEM_PIPELINES = {
20'scrapy_redis.pipelines.RedisPipeline': 300
21}
22
23#指定连接到redis时使用的端口和地址
24REDIS_HOST = 'localhost'
25REDIS_PORT = 6379
腾讯招聘分布式改写
-
分布式爬虫完成步骤
xxxxxxxxxx
21【1】首先完成非分布式scrapy爬虫 : 正常scrapy爬虫项目抓取
2【2】设置,部署成为分布式爬虫
-
分布式环境说明
xxxxxxxxxx
41【1】分布式爬虫服务器数量: 2(其中1台Windows,1台Ubuntu虚拟机)
2【2】服务器分工:
32.1) Windows : 负责数据抓取
42.2) Ubuntu : 负责URL地址统一管理,同时负责数据抓取
-
腾讯招聘分布式爬虫 - 数据同时存入1个Redis数据库
xxxxxxxxxx
221【1】完成正常scrapy项目数据抓取(非分布式 - 拷贝之前的Tencent)
2
3【2】设置settings.py,完成分布式设置
42.1-必须) 使用scrapy_redis的调度器
5SCHEDULER = "scrapy_redis.scheduler.Scheduler"
672.2-必须) 使用scrapy_redis的去重机制
8DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
9102.3-必须) 定义redis主机地址和端口号
11REDIS_HOST = '192.168.1.107'
12REDIS_PORT = 6379
13142.4-非必须) 是否清除请求指纹,True:不清除 False:清除(默认)
15SCHEDULER_PERSIST = True
16172.5-非必须) 在ITEM_PIPELINES中添加redis管道,数据将会存入redis数据库
18'scrapy_redis.pipelines.RedisPipeline': 200
1920【3】把代码原封不动的拷贝到分布式中的其他爬虫服务器,同时开始运行爬虫
21
22【结果】:多台机器同时抓取,数据会统一存到Ubuntu的redis中,而且所抓数据不重复
-
腾讯招聘分布式爬虫 - 数据存入MySQL数据库
xxxxxxxxxx
271"""和数据存入redis步骤基本一样,只是变更一下管道和MySQL数据库服务器的IP地址"""
2【1】settings.py
31.1) SCHEDULER = 'scrapy_redis.scheduler.Scheduler'
41.2) DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'
51.3) SCHEDULER_PERSIST = True
61.4) REDIS_HOST = '192.168.1.105'
71.5) REDIS_PORT = 6379
81.6) ITEM_PIPELINES = {'Tencent.pipelines.TencentMysqlPipeline' : 300}
91.7) MYSQL_HOST = '192.168.1.105'
1011【2】将代码拷贝到分布式中所有爬虫服务器
12
13【3】多台爬虫服务器同时运行scrapy爬虫
14
15# 赠送腾讯MySQL数据库建库建表语句
16"""
17create database tencentdb charset utf8;
18use tencentdb;
19create table tencenttab(
20job_name varchar(1000),
21job_type varchar(200),
22job_duty varchar(5000),
23job_require varchar(5000),
24job_address varchar(200),
25job_time varchar(200)
26)charset=utf8;
27"""
机器视觉与tesseract
-
概述
xxxxxxxxxx
121【1】作用
2处理图形验证码
3
4【2】三个重要概念 - OCR、tesseract-ocr、pytesseract
52.1) OCR
6光学字符识别(Optical Character Recognition),通过扫描等光学输入方式将各种票据、报刊、书籍、文稿及其它印刷品的文字转化为图像信息,再利用文字识别技术将图像信息转化为电子文本
7
82.2) tesseract-ocr
9OCR的一个底层识别库(不是模块,不能导入),由Google维护的开源OCR识别库
10
112.3) pytesseract
12Python模块,可调用底层识别库,是对tesseract-ocr做的一层Python API封装
-
安装tesseract-ocr
xxxxxxxxxx
91【1】Ubuntu安装
2sudo apt-get install tesseract-ocr
3
4【2】Windows安装
52.1) 下载安装包
62.2) 添加到环境变量(Path)
7
8【3】测试(终端 | cmd命令行)
9tesseract xxx.jpg 文件名
-
安装pytesseract
xxxxxxxxxx
131【1】安装
2sudo pip3 install pytesseract
34【2】使用示例
5import pytesseract
6# Python图片处理库
7from PIL import Image
8
9# 创建图片对象
10img = Image.open('test1.jpg')
11# 图片转字符串
12result = pytesseract.image_to_string(img)
13print(result)
补充 - 滑块缺口验证码案例
豆瓣网登录
-
案例说明
xxxxxxxxxx
61【1】URL地址: https://www.douban.com/
2【2】先输入几次错误的密码,让登录出现滑块缺口验证,以便于我们破解
3【3】模拟人的行为
43.1) 先快速滑动
53.2) 到离重点位置不远的地方开始减速
6【4】详细看代码注释
-
代码实现
xxxxxxxxxx
831"""
2说明:先输入几次错误的密码,出现滑块缺口验证码
3"""
4from selenium import webdriver
5# 导入鼠标事件类
6from selenium.webdriver import ActionChains
7import time
8
9# 加速度函数
10def get_tracks(distance):
11"""
12拿到移动轨迹,模仿人的滑动行为,先匀加速后匀减速
13匀变速运动基本公式:
14①v=v0+at
15②s=v0t+½at²
16"""
17# 初速度
18v = 0
19# 单位时间为0.3s来统计轨迹,轨迹即0.3内的位移
20t = 0.3
21# 位置/轨迹列表,列表内的一个元素代表0.3s的位移
22tracks = []
23# 当前的位移
24current = 0
25# 到达mid值开始减速
26mid = distance*4/5
27while current < distance:
28if current < mid:
29# 加速度越小,单位时间内的位移越小,模拟的轨迹就越多越详细
30a = 2
31else:
32a = -3
33
34# 初速度
35v0 = v
36# 0.3秒内的位移
37s = v0*t+0.5*a*(t**2)
38# 当前的位置
39current += s
40# 添加到轨迹列表
41tracks.append(round(s))
42# 速度已经达到v,该速度作为下次的初速度
43v = v0 + a*t
44return tracks
45# tracks: [第一个0.3秒的移动距离,第二个0.3秒的移动距离,...]
46
47
48# 1、打开豆瓣官网 - 并将窗口最大化
49browser = webdriver.Chrome()
50browser.maximize_window()
51browser.get('https://www.douban.com/')
52
53# 2、切换到iframe子页面
54login_frame = browser.find_element_by_xpath('//*[@id="anony-reg-new"]/div/div[1]/iframe')
55browser.switch_to.frame(login_frame)
56
57# 3、密码登录 + 用户名 + 密码 + 登录豆瓣
58browser.find_element_by_xpath('/html/body/div[1]/div[1]/ul[1]/li[2]').click()
59browser.find_element_by_xpath('//*[@id="username"]').send_keys('15110225726')
60browser.find_element_by_xpath('//*[@id="password"]').send_keys('zhanshen001')
61browser.find_element_by_xpath('/html/body/div[1]/div[2]/div[1]/div[5]/a').click()
62time.sleep(4)
63
64# 4、切换到新的iframe子页面 - 滑块验证
65auth_frame = browser.find_element_by_xpath('//*[@id="TCaptcha"]/iframe')
66browser.switch_to.frame(auth_frame)
67
68# 5、按住开始滑动位置按钮 - 先移动180个像素
69element = browser.find_element_by_xpath('//*[@id="tcaptcha_drag_button"]')
70# click_and_hold(): 按住某个节点并保持
71ActionChains(browser).click_and_hold(on_element=element).perform()
72# move_to_element_with_offset(): 移动到距离某个元素(左上角坐标)多少距离的位置
73ActionChains(browser).move_to_element_with_offset(to_element=element,xoffset=180,yoffset=0).perform()
74
75# 6、使用加速度函数移动剩下的距离
76tracks = get_tracks(28)
77for track in tracks:
78# move_by_offset() : 鼠标从当前位置移动到某个坐标
79ActionChains(browser).move_by_offset(xoffset=track,yoffset=0).perform()
80
81# 7、延迟释放鼠标: release()
82time.sleep(0.5)
83ActionChains(browser).release().perform()
Fiddler抓包工具
-
配置Fiddler
xxxxxxxxxx
91【1】Tools -> Options -> HTTPS
21.1) 添加证书信任: 勾选 Decrypt Https Traffic 后弹出窗口,一路确认
31.2) 设置之抓浏览器的包: ...from browsers only
4
5【2】Tools -> Options -> Connections
62.1) 设置监听端口(默认为8888)
7
8【3】配置完成后重启Fiddler('重要')
93.1) 关闭Fiddler,再打开Fiddler
-
配置浏览器代理
xxxxxxxxxx
101【1】安装Proxy SwitchyOmega谷歌浏览器插件
2
3【2】配置代理
42.1) 点击浏览器右上角插件SwitchyOmega -> 选项 -> 新建情景模式 -> myproxy(名字) -> 创建
52.2) 输入 HTTP:// 127.0.0.1 8888
62.3) 点击 :应用选项
78【3】点击右上角SwitchyOmega可切换代理
9
10【注意】: 一旦切换了自己创建的代理,则必须要打开Fiddler才可以上网
-
Fiddler常用菜单
xxxxxxxxxx
81【1】Inspector :查看数据包详细内容
21.1) 整体分为请求和响应两部分
34【2】Inspector常用菜单
52.1) Headers :请求头信息
62.2) WebForms: POST请求Form表单数据 :<body>
7GET请求查询参数: <QueryString>
82.3) Raw : 将整个请求显示为纯文本
移动端app数据抓取
-
方法1 - 手机 + Fiddler
xxxxxxxxxx
11设置方法见文件夹 - 移动端抓包配置
-
方法2 - F12浏览器工具
有道翻译手机版破解案例
xxxxxxxxxx
17
1
import requests
2
from lxml import etree
3
4
word = input('请输入要翻译的单词:')
5
6
post_url = 'http://m.youdao.com/translate'
7
post_data = {
8
'inputtext':word,
9
'type':'AUTO'
10
}
11
12
html = requests.post(url=post_url,data=post_data).text
13
parse_html = etree.HTML(html)
14
xpath_bds = '//ul[@id="translateResult"]/li/text()'
15
result = parse_html.xpath(xpath_bds)[0]
16
17
print(result)