两周从爬虫小白变大神,看完你就知道我不是标题党了【五万字教程,建议收藏】
时间:2023-04-22 13:07:01
大家好,我是辣条,今天给大家带来最硬核的爬虫教程。
目录
Python爬虫第一天
什么是爬虫
爬虫与Web后端服务之间的关系
Python爬虫技术相关库
常见的反爬虫策略
爬虫库urllib【重要】
作业
爬虫第二天
回顾知识点
requests库【重点】
数据分析方法之一xpath
绝对路径
相对路径
数据提取
位置条件
属性条件
在Python中应用
作业
爬虫第三天
回顾知识点
requests库
xpath解析
扩展封装ES-SDK
数据的正则分析
扩展Linux文件权限
re面试中的问题
作业
爬虫第四天
回顾知识点
re正则
进程和线程
BS4数据解析
协程爬虫
协程的三种方式
协程第三方框架
动态js渲染
Selenium
Splash
作业
爬虫最五天
回顾知识点
协程的爬虫
Seleinum库
Chrome-headless
Splash渲染
下载镜像
启动镜像
render.html接口
自动化测试
单元测试
集成测试
作业
爬虫第六天
回顾知识点
selenium框架
docker
日志模块进阶
日志格式
日志模块的核心
scrapy框架
scrapy架构组成
scrapy指令
Response类
Request类
作业
爬虫第七天
回顾知识点
scrapy框架
scrapy数据管道
指令方式存储
Pipeline
定量爬虫
基于信号方式
下载中间件
爬虫中间件
下载中间件 [重点]
作业
爬虫第八天
回顾知识点
数据处理
中间件
规则爬虫
规则爬虫【重】
LinkExtractor 类
核心的类
图片管道
使用ImagesPipeline
自定义ImagesPipeline
其它技术点
日志
post请求
Selenium中间件
作业
爬虫第九天
回顾知识点
Selenium下载中间件
分布式爬虫
什么是分布式
常见消息队列
scrapy-redis
爬虫程序部署
scrapyd
docker部署
作业
爬虫第十天
回顾爬虫技术
网络请求
数据解析
数据存储
爬虫框架
mongodb
docker部署
数据结构
常用操作
作业
Python爬虫第一天
学习内容:
-
什么是爬虫(Spider)
-
爬虫与Web后端服务之间的关系
-
Python爬虫技术的相关库
-
常见反爬虫的策略
-
爬虫库urllib【重要】
什么是爬虫
爬虫Spider的概念
爬虫用于爬取数据, 又称之为数据采集程序。
爬取的数据来源于网络,网络中的数据可以是由Web服务器(Nginx/Apache)、数据库服务器(MySQL、Redis)、索引库(ElastichSearch)、大数据(Hbase/Hive)、视频/图片库(FTP)、云存储等(OSS)提供的。
爬取的数据是公开的、非盈利的。
Python爬虫
使用Python编写的爬虫脚本(程序)可以完成定时、定量、指定目标(Web站点)的数据爬取。主要使用多(单)线程/进程、网络请求库、数据解析、数据存储、任务调度等相关技术。
Python爬虫工程师,可以完成接口测试、功能性测试、性能测试和集成测试。
爬虫与Web后端服务之间的关系
爬虫使用网络请求库,相当于客户端请求, Web后端服务根据请求响应数据。
爬虫即向Web服务器发起HTTP请求,正确地接收响应数据,然后根据数据的类型(Content-Type)进行数据的解析及存储。
爬虫程序在发起请求前,需要伪造浏览器(User-Agent指定请求头),然后再向服务器发起请求, 响应200的成功率高很多。
Python爬虫技术的相关库
网络请求:
-
urllib
-
requests / urllib3
-
selenium(UI自动测试、动态js渲染)
-
appium(手机App 的爬虫或UI测试)
数据解析:
-
re正则
-
xpath
-
bs4
-
json
数据存储:
-
pymysql
-
mongodb
-
elasticsearch
多任务库:
-
多线程 (threading)、线程队列 queue
-
协程(asynio、 gevent/eventlet)
爬虫框架
-
scrapy
-
scrapy-redis 分布式(多机爬虫)
常见反爬虫的策略
-
UA(User-Agent)策略
-
登录限制(Cookie)策略
-
请求频次(IP代理)策略
-
验证码(图片-云打码,文字或物件图片选择、滑块)策略
-
动态js(Selenium/Splash/api接口)策略
爬虫库urllib【重要】
urllib.request模块
简单的请求
from urllib.request import urlopen
# 发起网络请求
resp = urllopen('http://www.hao123.com')
assert resp.code == 200
print('请求成功')
# 保存请求的网页
# f 变量接收open()函数返回的对象的__enter__()返回结果
with open('a.html', 'wb') as f:
f.write(resp.read())
urlopen(url, data=None)可以直接发起url的请求, 如果data不为空时,则默认是POST请求,反之为GET请求。
resp是http.client.HTTPResponse类对象。
带请求头的请求
from urllib.request import Request
def search_baidu():
# 网络资源的接口(URL)
url = 'https://www.baidu.com'
# 生成请求对象,封装请求的url和头header
request = Request(url,
headers={
'Cookie': 'BIDUPSID=16CECBB89822E3A2F26ECB8FC695AFE0; PSTM=1572182457; BAIDUID=16CECBB89822E3A2C554637A8C5F6E91:FG=1; BD_UPN=123253; H_PS_PSSID=1435_21084_30211_30283; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; H_PS_645EC=6f7aTIObS%2BijtMmWgFQxMF6H%2FhK%2FcpddiytCBDrefRYyFX%2B%2BTpyRMZInx3E',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'
})
response = urlopen(request) # 发起请求
assert response.code == 200
print('请求成功')
# 读取响应的数据
bytes_ = response.read()
# 将响应的数据写入文件中
with open('index.html', 'wb') as file:
file.write(bytes_)
任务1:收集Http协议的报文头的哪些Key
urllib.parse模块
此模块有两个核心的函数:
-
quote() 仅对中文字符串进行url编码;
-
urlencode() 可以针对一个字典中所有的values进行编码,然后转成key=value&key=value的字符串。
"""
复杂的GET请求,多页面请求下载
"""
from urllib.request import Request, urlopen
from urllib.parse import urlencode
import ssl
import time
ssl._create_default_https_context = ssl._create_unverified_context
url = 'https://www.baidu.com/s?'
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
'Cookie': 'BIDUPSID=16CECBB89822E3A2F26ECB8FC695AFE0; PSTM=1572182457; BAIDUID=16CECBB89822E3A2C554637A8C5F6E91:FG=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1573184257; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; H_PS_PSSID=1435_21084_30211_30283; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; PSINO=1; to_lang_often=%5B%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%2C%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%5D; APPGUIDE_8_2_2=1; yjs_js_security_passport=0927713bf2c240ca607108086d07729426db4dbb_1577084843_js; __yjsv5_shitong=1.0_7_c3620451e4363f4aed30cbe954abf8942810_300_1577084847314_223.255.14.197_2d7151e0; from_lang_often=%5B%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%5D',
'x-requested-with': 'XMLHttpRequest'
}
params = {
'wd': '',
'pn': 0 # 0, 10, 20, 30 ... = (n-1)*10
}
def pages_get(wd):
params['wd'] = wd
for page in range(1, 101):
params['pn'] = (page-1)*10
page_url = url+urlencode(params)
resp = urlopen(Request(page_url,
headers=headers))
assert resp.code == 200
file_name = 'baidu_pages/%s-%s.html' % (wd, page)
with open(file_name, 'wb') as f:
bytes_ = resp.read()
f.write(bytes_)
print(f'{file_name} 写入成功!')
time.sleep(0.5)
print('下载 %s 100页成功!' % wd)
if __name__ == '__main__':
pages_get('Python3.6')
HTTP处理器
urllib的请求处理器,主要用于urllib.request.build_opener()
函数参数,表示构造一个由不同处理组成的伪浏览器。
HTTPHandler
处理Http协议的请求处理。
5HTTPCookieProcessor
处理Cookie的处理器,创建类实例时,需要提供http.cookiejar.CookieJar
类的实例对象。
ProxyHandler
作业
-
写出Python上下文的两个核心函数
__enter__(self) __exit__(self, except_type, except_value, except_tb)
-
写出正则中的(), [] , {} 三个符号的作用
( ) 用于分组的符号 [ ] 指定匹配字符的范围,如 [a-c_B-F] { } 指定匹配的长度(量词表示)
-
写出pymysql.Connect()连接数据库的核心参数
Connect(host, port=3306, user, password, db, charset)
-
豆瓣动作电影排行榜
-
肯德基店铺位置
爬虫第二天
回顾知识点
核心的网络请求库 -> urllib库
-
urllib.request 模块
-
urlopen(url | request: Request, data=None) data是bytes类型
-
urlretrieve(url, filename) 下载url的资源到指定的文件
-
build_opener(*handlder) 构造浏览器对象
-
opener.open(url|request, data=None) 发起请求
-
-
Request 构造请求的类
data={ 'wd': '' } # urlencode(data) => 'wd=%f5%e6%e6%f5%e6%e6' request = Request(url, data=urlencode(data).encode())
-
HTTPHandler HTTP协议请求处理器
-
ProxyHandler(proxies={'http': 'http://proxy_ip:port'}) 代理处理
-
HTTPCookieProcessor(CookieJar())
-
http.cookiejar.CookieJar 类
-
-
-
urllib.parse模块
-
quote(txt) 将中文字符串转成url编码
-
urlencode(query: dict) 将参数的字典转成url编码,结果是key=value&key=value形式,即以
application/x-www-form-urlencoded
作为url编码类型。
-
requests库【重点】
requests库也是一个网络请求库, 基于urllib和urllib3封装的便捷使用的网络请求库。
安装环境
pip install requests -i https://mirrors.aliyun.com/pypi/simple
核心的函数
-
requests.request() 所有请求方法的基本方法
以下是request()方法的参数说明
-
method: str 指定请求方法, GET, POST, PUT, DELETE
-
url: str 请求的资源接口(API),在RESTful规范中即是URI(统一资源标签识符)
-
params: dict , 用于GET请求的查询参数(Query String params);
-
data: dict , 用于POST/PUT/DELETE 请求的表单参数(Form Data)
-
json: dict 用于上传json数据的参数, 封装到body(请求体)中。请求头的Content-Type默认设置为
application/json
-
files: dict, 结构 {'name': file-like-object | tuple}, 如果是tuple, 则有三种情况:
-
('filename', file-like-object)
-
('filename', file-like-object, content_type)
-
('filename', file-like-object, content_type, custom-headers)
指定files用于上传文件, 一般使用post请求,默认请求头的
Content-Type
为multipart/form-data
类型。 -
-
headers/cookies : dict
-
proxies: dict , 设置代理
-
auth: tuple , 用于授权的用户名和口令, 形式('username', 'pwd')
-
-
requests.get() 发起GET请求, 查询数据
可用参数:
-
url
-
params
-
json
-
headers/cookies/auth
-
-
requests.post() 发起POST请求, 上传/添加数据
可用参数:
-
url
-
data/files
-
json
-
headers/cookies/auth
-
-
requests.put() 发起PUT请求, 修改或更新数据
-
requests.patch() HTTP幂等性的问题,可能会出现重复处理, 不建议使用。用于更新数据
-
requests.delete() 发起DELETE请求,删除数据
requests.Respose
以上的请求方法返回的对象类型是Response, 对象常用的属性如下:
-
status_code 响应状态码
-
url 请求的url
-
headers : dict 响应的头, 相对于urllib的响应对象的getheaders(),但不包含cookie。
-
cookies: 可迭代的对象,元素是Cookie类对象(name, value, path)
-
text : 响应的文本信息
-
content: 响应的字节数据
-
encoding: 响应数据的编码字符集, 如utf-8, gbk, gb2312
-
json(): 如果响应数据类型为
application/json
,则将响应的数据进行反序化成python的list或dict对象。-
扩展-javascript的序列化和反序列化
-
JSON.stringify(obj) 序列化
-
JSON.parse(text) 反序列化
-
-
数据解析方式之xpath
xpath属于xml/html解析数据的一种方式, 基于元素(Element)的树形结构(Node > Element)。选择某一元素时,根据元素的路径选择,如
/html/head/title
获取标签。
绝对路径
从根标签开始,按tree结构依次向下查询。
如 /html/body/table/tbody/tr。
相对路径
相对路径可以有以下写法
-
相对于整个文档
//img
查找出文档中所有的
标签元素 -
相对于当前节点
//table
假如当前节点是