导图社区 python3网络爬虫开发实战自学笔记
运行结果:['霸王别姬 - Farewell My Concubine', '这个杀手不太冷 - Léon', '肖申克的救赎 - The Shawshank Redemption', '泰坦尼克号 - Titanic', '罗马假日 - Roman Holiday', '唐伯虎点秋香 - Flirting Scholar', '乱世佳人 - Gone with the Wind'。
编辑于2023-01-31 19:36:33 上海python3-scrape
1chapter-foundation of crawler
1.1HTTP basic principle
1.URI and URL
scheme (protocol)
http
https
ftp
username;password
hostname
port
http:80
http:443
path
parameters
用得较少
query
multi-query use"&"
for example:https://www.baidu.com/s?wd=nba&ie=utf-8
fragment:片段,资源内部书签
单页面路由
管理前端框架
Vue
React
HTML锚点
控制一个页面打开时自动滑动到某个特定的位置
2.HTTP and HTTPS
HyperText Transfer Protocol
2015年HTTP2.0
多路复用
服务器推送
头信息压缩
二进制协议
HyperText Transter Protocol over Secure Socket Layer
建立一个信息安全通道,保证数据传输的安全性
确认网站的真实性
通过锁头标志查看网站认证
通过CA机构颁发安全签章
苹果公司2017年1月开始
iOS App 全部改为使用HTTPS加密
从Chrome56开始亮出风险提示
腾讯小程序官方需求文档要求后台使用HTTPS请示进行网络通信
HTTPS是大势所趋
其下层:TCP/IP传输协议 即传输控制/网络协议 也叫作网络通讯协议
共分四层
应用层
Telnet
FTP
SMTP
传输层
UDP
TCP
连接时三次握手
断开时四次挥手
网络层
ICMP
IP
IGMP
数据链路层 也叫网络访问层
ARP
RARP
3.HTTP请示过程
Name
请求的名称,一般会用URL的最后一部分作为名称
Status
响应的状态码。200或OK表示响应正常。
Protocol
请求的协议类型。h2代表HTTP2.0版本
Type
请求的文档类型。
Initiator
请求源。用来标记请求是由哪个对象或进程发起的。
Size
请求资源的大小。from cache 表示从缓存中取得资源。
Time
请求到响应的总时间。
Waterfall
网络请求的可视化瀑布流。
4.Request
Method
常用
get
参数包涵在URL中
提交的数据最多1024字节
post
参数通过表单传输 比如用户名和密码
提交的数据没有限制
不常用
head
类似于get,只获取报头。
put
从客户端向服务器传输并替换指定的内容
delete
请求服务器删除指定的页面
connect
让服务器替客户端访问其他网页
options
允许客户端查看服务器的性能
trace
回显服务器收到的请求。主要用于测试或诊断。
URL
可以唯一确定客户端想请求的资源。
Headers
Accept:
请求报头域,用于指定客户端可接受哪些类型的信息。
Accept-Language:
用于指定客户端可接受的语言类型。
Accept-Encoding:
用于指定客户端可接受的内容编码。
Host:
IP和端口号。
Cookie:
也常用复数。网站为了辨别用户,进行会话跟踪而存储用户本地的数据,用以维持当前访问会话。比如登录的用户名和密码,每次刷新或请求该站点的其他页面,就能发现是否处于登录状态。
Referer:
用于标识请求是从哪个页面发过来的,服务器可以拿到这个信息并做相应的处理,如做来源统计、防盗链处理等。
User-Agent:
简称UA,这是一个特殊的字符串头,可以使服务器识别客户端使用的操作系统及版本、浏览器等信息。做爬虫的时候,可以伪装为浏览器;如果不加,可能被识别出来。
Content-Type:
也叫互联网媒体类型(Internet Media Type) 或者MIME类型。如:
text/html代表HTML格式
image/gif代表GIF图片
application/json代表JSON类型
Body
一般承载的是POST中的表单数据。get请求体为空。 Content-Type和POST提交数据方式的关系:
application/x-www-form-urlencoded
表单数据
multipart/form-data
表单文件上传
application/json
序列化JSON数据
text/xml
XML数据
5.Response
Status-Code
200
成功
404
未找到
500
服务器内部发生错误
100-505
若干意思
Headers
Date
标识响应产生的时间
Last-Modified
指定资源的最后修改时间
Content-Encoding
响应内容的编码
Server
服务器信息,例如名称、版本号等
Content-Type
文档类型
text/html返回HTML文档
image/jpeg返回图片
application/x-javascript返回JavaScript文件
Set-Cookie
设置Cookie.告诉浏览器需要将此内容放在Cookie中,下次请求时将Cookie携带上
Expires
响应的过期时间
可以让代理服务器将加载的内容更新到缓存中,下次再访问可以直接加载,缩短访问时间
Body
text/html返回HTML文档
image/jpeg返回图片
注意:以二进制形式出现
application/x-javascript返回JavaScript文件
6.HTTP2.0
主要优化
二进制分帧层
帧
数据通信 最小的单位
请求头帧 Request Headers Frame
请求体/数据帧 Request Data Frame
数据流
虚拟通道,可以承载双向消息,每个流都有一唯一的整数ID标识
消息
与逻辑请求或响应消息对应的完整的一系列帧
多路复用
不用再以TCP连接的方式去实现多路并行,客户端和服务端可以将HTTP消息分解为互不依赖的帧,交错发送,最后再在另一端把它们重新组装起来
并行交错发送多个请求,互不影响
并行交错发送多个响应,互不干扰
使用一个连接并行发送多个请求和响应
不必再为绕过HTTP1.X限制而做很多工作
消除不必要的延迟和提高现有网络容量的利用率,从而减少页面加载时间,提高数据传输性能
同域名只需要占用一个TCP连接,消除多个TCP连接带来的延时和内存消耗
并行交错发送多个请求和响应,且互不影响
每个请求都可以带一个31位的优先值,0表示最高优先级,数据越大优先级越低。客户端和服务端可以在处理不同的流时采取不同的策略,以最优先的方式发送流、消息和帧。
流控制
阻止发送端向接收端发送大量数据的机制
客户端请求了一个优先级较高的大型视频资源,但用户已经暂停观看
代理服务器将较快的下游连接调整为与较慢上游资源相适应的速度,从而控制资源利用率
构建块
流控制具有方向性。
流控制的窗口大小是动态调整的。
流控制无法停用。
服务端推送
对客户端一个请求发送多个响应。比如有些资源 客户端是一定会请求的,服务端就会提前推送,以减少响应延迟。
但不推送第三方资源,以确保安全
子主题
1.2Web basic
1.网页的组成
HTML
骨架: 内容和结构
通过标签来定义的节点
嵌套
组合
形成复杂的层次关系
CSS
皮肤:样式
Cascading Style Sheets,即层叠样式表
目前唯一的网页页面排版样式标准
JavaScript
肌肉:行为
脚本语言
2.网页的结构
开头定义文档类型
<!DOCTYPE html>
最外层
<html> </html>
<head> </head>
对网页的配置和引用进行定义,比如
编码<meta charset="UTF-8">
标题<title>this is a Demo</title>
<body> </body>
网页正文显示的内容
区块<div></div>
id该区块的唯一标识
class经常与CSS配合使用设定样式
h2代表一个二级标题
<p> </p>
代表一个段落
3.节点树及节点之间的关系
所有标签定义的内容都是节点,构成结点树,也叫HTML DOM
DOM
Document Object Model文档对象模型
整个网站文档是一个文档的节点
每个html标签对应一个根节点
节点内的文本是文本节点,比如a节点代表一个超链接,它内部的文本也被认为是一个文本节点
每个节点的属性都是属性节点,比如a节点有一个href属性,它就是一个属性节点
注释是注释节点
所有节点
都可以被JavaScript 访问
元素都可以被修改、创建或删除
形成层级关系
父parent
子child
兄弟sibling
顶端节点称为root
4.CSS选择器
定位节点,最常用的三种方式
id
#contaiter(id的值)
class
.warpper(class的值)
标签名
如二级标题可以直接用h2
支持嵌套
利用空格把各个选择器分隔开,代表嵌套关系
#container .wrapper p.text 代表先选择id为container的节点,再选择其内部class为wrapper的节点,再进一步选择这个节点内部的class为text的节点。
其他语法规则
子主题
子主题
子主题
子主题
子主题
子主题
还有一个比较常用的选择器
XPath
1.3 crawler basic principle
1.概述
获取网页
urllib
requests
提取信息
万能之法-正则表达式
构造正则表达式复杂且容易出错
根据
网页节点属性
CSS选择器
XPath
来提取网页信息
Beautiful Soup
pyquery
lxml
高效提取节点的属性、文本值
保存数据
文本
text
json
数据库
MySQL
MongoDB
服务器
SFTP
自动化程序
爬虫
2.怎样爬取数据
HTML
JSON
API接口多采用该形式
方便数据传输和解析
二进制数据
图片
音频
视频
扩展名文件
CSS
JavaScript
配置文件
3. JavaScript渲染的页面
前端模块化工具
后台Ajax接口,可以借助
Selenium
Splash
Pyppeteer
Playwright
模拟JavaScript渲染
1.4Session and Cookie
1.静态网页和动态网页
静态HTML
动态
JSP
PHP
Python
功能强大、内容丰富
可以实现用户登录和注册
2.无状态HTTP
3.Session登记,在服务器端
会话:有始有终的一系列动作、消息
web会话中存储特定用户的属性及其配置信息
4.Cookie收据,在客户端
收据或凭证,且有有效期
1.5 Proxy basic principle
1.基本原理
2.代理的作用
3.爬虫代理
4.代理分类
1.6Multi-threaded and multi-process
1.多线程的含义
2.并发和并行
3.多线程适用场景
4.多进程的含义
5.python中的多线程和多进程
2chapter-Basic library
2.1urllib
1.request模块:发送请求
urlopen,基于urllib.request模块,其响应是HTTPRosne类型对象
read得到响应的网页内容
readinto读取本身的信息
getheader响应头
getheaders响应头
fileno
msg消息
version版本
status获取状态
reason诊断原因
debuglevel补丁水平
closed关闭
data参数(附加数据)
可选参数。添加该参数是,需要使用bytes方法将参数转化字节流编码格式的内容,即bytes类型。一旦传递了该参数,请求方式就不再是GET,而是POST.
timeout参数
如果不设置,则使用全局默认时间
其他参数
context
必须是ssl.SSLContext类型,用来指定SSL的设置
cafile
CA证书
capath
CA路径
Request
比Urlopen强大,主要参数
URL必传参数
data,要传数据,必须传bytes类型的。如果数据是字典,可以先用urllib.parse模块里的urlencode方法进行编码。
headers,是一个字典,这就是请求头
既可通过headers参数直接构造
也可以通过调用请求实例的add_header方法添加
典型的方法就是伪装浏览器
origin_req_host
指的是请求方的host名称或IP地址
unverifiable
表示请求是无法验证的
method
是一个字符串,用来指示请求使用的方法,如GET,POST,PUT等
高级用法
验证
代理
Cookie
2.error模块:处理异常
URLError
HTTPError
HTTPError为URLError的子类,专门处理HTTP请求错误
code
返回状态码
404
不存在
500
服务器错误
reason
同父类一样,返回错误的原因
headers
返回请求头
3.parse模块:解析链接
urlparse
实现URL的识别和分段,标准的URL
scheme
:号前的内容,代表协议(计划、方案)
netloc
第一个/号前,代表域名
path
第一个/号后,代表访问路径
params
;后面代表参数
query
?后面是查询条件query,一般用作GET类型的URL
fragment
#号后面是锚点,用于直接定位页面内部的下接位置
比如:
from urllib.parse import urlparse result=urlparse('https//www.baidu.com/index.html;user?id=5#comment') print(result)
运行结果:ParseResult(scheme='', netloc='', path='https//www.baidu.com/index.html', params='user', query='id=5', fragment='comment')
API用法
urlstring
必填项,待解的URL
scheme
这是默认的协议
allow_fragments
允许锚点
urlunparse
用于构造URL,如:
from urllib.parse import urlunparse data=['https','www.baidu.com','index.html','user','a=6','comment'] print(urlunparse(data))
运行结果:https://www.baidu.com/index.html;user?a=5#comment
接收的参数是一个可以迭代对象,长度必须是6
参数可以是列表类型,也可以用元组或其他特定的数据结构
urlsplit
比如:
from urllib.parse import urlsplit result=urlsplit('https//www.baidu.com/index.html;user?id=5#comment') print(result)
运行结果:SplitResult(scheme='', netloc='', path='https//www.baidu.com/index.html;user', query='id=5', fragment='comment')
urlunsplit
from urllib.parse import urlunsplit data=['https','www.baidu.com','index.html','a=6','comment'] print(urlunsplit(data))
https://www.baidu.com/index.html?a=6#comment
urljoin链接合并
需要提供两个参数
base_url
scheme
netloc
path
新的链接
如果新的链接里不存在基础链接的三项内容,则以基础链接进行补充;如果存在,就使用新的链接
通过urljoin,我们可以轻松实现链接的解析、拼合与生成
urlencode序列化
构造GET请求参数非常有用,实例如下:
from urllib.parse import urlencode params={ ‘name':'germey', 'age':'25' } base_url='https://www.baidu.com?' url=base_url+urlencode(params) print(url)
运行结果:https://www.baidu.com?name=germey&age=25
parse_qs反序列化
可以将一串GET请求参数转回字典,实例如下:
from urllib.parse import parse_qs query='name=germey&age=25' print(parse_qs(query))
运行结果:{'name': ['germey'], 'age': ['25']}
parse_qsl反元组化
可以将一串GET请求参数转化为元组列表,实例如下:
from urllib.parse import parse_qsl query='name=germey&age=25' print(parse_qsl(query))
运行结果:[('name', 'germey'), ('age', '25')]
quote
可以将中文字符转化为URL编码,实例如下:
from urllib.parse import quote keyword='壁纸' url='https://www.baidu.com/s?wd='+quote(keyword) print(url)
运行结果:https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8
nuquote
可以对URL编码进行解码为中文字符,实例如下:
from urllib.parse import unquote url='https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8' print(unquote(url))
运行结果:https://www.baidu.com/s?wd=壁纸
4.robotparser模块:Robots协议
也称爬虫协议、机器人协议
set_url:设置robots.txt文件的链接
read:读取robots.txt文件并进行分析
parse:用来解析robots.txt文件,传入其中的参数是robots文件中的某些内容
can_fetch:该方法有两个参数
User_Agent
要抓取的URL
返回结果true或false表示是否可能抓取URL
2.2requests
比urllib库强大
1.安装
2.实例
urllib中的urlopen方法实际是以GET方式请求网页,requests库中相应的方法就是get方法,实例如下:
import requests r=requests.get('https://www.baidu.com/') print(type(r)) print(r.status_code) print(type(r.text)) print(r.text[:100]) print(r.cookies)
<class 'requests.models.Response'> 200 <class 'str'> <!DOCTYPE html> <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charse <RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
import requests r=requests.get('https://www.httpbin.org/get') r=requests.post('https://www.httbin.org/post') r=requests.put('https://www.httbin.org/put') r=requests.delete('https://www.httbin.org/delete') r=requests.patch('https://www.httbin.org/patch')
3.GET请求
基本实例
import requests data={ 'name':'germey', 'age':'25' } r=requests.get('https://www.httpbin.org/get',params=data) print(r.text)
运行结果:{ "args": { "age": "25", "name": "germey" }, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Host": "www.httpbin.org", "User-Agent": "python-requests/2.25.1", "X-Amzn-Trace-Id": "Root=1-63bc0565-1397a9c039dc032665ff384b" }, "origin": "139.227.3.121", "url": "https://www.httpbin.org/get?name=germey&age=25" }
抓取网页
import requests,re r=requests.get('https://ssr1.scrape.center/') pattern=re.compile('<h2.*?>(.*?)</h2>',re.S) titles=re.findall(pattern,r.text) print(titles)
运行结果:['霸王别姬 - Farewell My Concubine', '这个杀手不太冷 - Léon', '肖申克的救赎 - The Shawshank Redemption', '泰坦尼克号 - Titanic', '罗马假日 - Roman Holiday', '唐伯虎点秋香 - Flirting Scholar', '乱世佳人 - Gone with the Wind', '喜剧之王 - The King of Comedy', '楚门的世界 - The Truman Show', '狮子王 - The Lion King']
抓取二进制数据
图片
音频
视频
添加请求头
import requests headers={ 'User-Agent':'Mozilla/5.0(Macintosh;Intel Mac OS X 10_11_4) AppleWebKit/537.36(KHTML,like Gecko) Chrome/52.0.2743.116 Safari/ 537.36' } r=requests.get('https://ssr1.scrape.center/',headers=headers) print(r.text)
4.POST请求
提交数据,实例如下:
import requests data={'name':'yongjun','age':'23'} r=requests.post('https://www.httpbin.org/post',data=data) print(r.text)
运行结果: { "args": {}, "data": "", "files": {}, "form": { "age": "23", "name": "yongjun" }, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Content-Length": "19", "Content-Type": "application/x-www-form-urlencoded", "Host": "www.httpbin.org", "User-Agent": "python-requests/2.25.1", "X-Amzn-Trace-Id": "Root=1-63bcb516-3d167b7a13b0e7410681445a" }, "json": null, "origin": "139.227.3.121", "url": "https://www.httpbin.org/post" }
5.响应
内容
text
content
状态码status_code
import requests r=requests.get('https://ssr1.scrape.center/') print('Request Successfully ') if r.status_code==requests.codes.ok else exit()
响应头headers
CaseInsensitiveDict
cookies
Requests-CookieJar
请求历史history
链接URL
6.高级用法
文件上传
import requests files={'file':open('22秋行政管理课程梳理.xlsx','rb')} r=requests.post('https://www.httpbin.org/post',files=files) print(r.text)
Cookie设置
import requests r=requests.get('https://www.baidu.com') print(r.cookies) for key,value in r.cookies.items(): print(key+'='+value)
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]> BDORZ=27315
items方法将Cookie转化为元组组成的列表,遍历输出每一个Cookie条目的名称和值,实现对Cookie的遍历解析
也可以直接用Cookie来维持登录状态。
子主题
Session维持
import requests s=requests.Session() s.get('https://www.httpbin.org/cookies/set/number/123456') r=s.get('https://www.httpbin.org/cookies') print(r.text)
{ "cookies": { "number": "123456" } }
SSL证书验证
import requests from requests.packages import urllib3 urllib3.disable_warnings() response=requests.get('https://ssr2.scrape.center/',verify=False) print(response.status_code)
200
timeout超时设置
import requests r=requests.get('https://www.httpbin.org/get',timeout=1) print(r.status_code)
200
可以分别指定用作连接和读取的timeout
import requests r=requests.get('https://www.httpbin.org/get',timeout=(5,6)) print(r.status_code)
200
也可以直接将timeout设置成为None或直接留空
import requests r=requests.get('https://www.httpbin.org/get',timeout=None)) print(r.status_code)
200
import requests r=requests.get('https://www.httpbin.org/get') print(r.status_code)
200
身份认证
import requests from requests.auth import HTTPBasicAuth r=requests.get('https://ssr3.scrape.center/',auth=HTTPBasicAuth('admin','admin')) print(r.status_code)
200
可以更加简洁,直接传入元组,默认使用HTTPBasicAuth这个类来认证
import requests from requests.auth import HTTPBasicAuth r=requests.get('https://ssr3.scrape.center/',auth=('admin','admin')) print(r.status_code)
200
proxies代理设置
http://user:password@host:port
Prepared Request有准备的请求
2.3正则表达式
1.实例引进,详见63-64页
2.match
概念:检测传入的
正则表达式
字符串
二者匹配情况,包括两个方法
group输出匹配到的内容
span输出匹配的范围
实例:
import re content='Hello 123 4567 World_This is a Regex Demo' print(len(content)) r=re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}',content) print(r.group()) print(r.span())
41 Hello 123 4567 World_This (0, 25)
匹配目标
使用括号,可以实现对group进行分组,如group(1)、group(2)
通用匹配
.*
.匹配任意字符(除换行符)
*匹配前面的字符无限次
二者组合可以匹配任意字符
实例:
import re content='Hello 123 4567 World_This is a Regex Demo' print(len(content)) r=re.match('^Hello.*Deimo$',content) print(r.group()) print(r.span())
41 Hello 123 4567 World_This (0, 25)
贪婪与非贪婪
贪婪.*
在匹配字符串结尾时,最好使用贪婪模式
非贪婪.*?
正常情况下尽可能多的使用非贪婪模式,但在结尾最好不要用,防止什么也没有
实例:
import re content='Hello 123 4567 World_This is a Regex Demo' print(len(content)) r=re.match('^He.*?(\d+).*Deimo$',content) print(r) print(r.group(1))
41 Hello 123 4567 World_This (0, 25)
修饰符
用来控制匹配模式的标志
较为常见的用法
re.S(包括换行符在内的所有字符
在网页匹配中经常用到
re.I
使匹配对大小写不敏感
其他的修饰符
re.L
实现本地化识别(locale-aware)匹配
re.M
多行匹配,影响^和$
re.U
根据Unicode字符集解析字符。这个标志会影响\w、\W、\b、\B
子主题
re.X
该标志能够给予你更灵活的格式,以便将正则表达式书写得更易于理解
转义匹配
使用反斜杠\
3.search
match必须从头开始匹配,而search则不需要从头开始,它在匹配时会扫描整个字符串,然后返回第一个匹配成功的结果。
html='''<div id="songs-list"> <h2 class="title">经典老歌</h2> <p class="introduction"> 经典老歌列表 </p> <ul id="list" class="list-group"> <li data-view="2">一路上有你</li> <li data-view="7"> <a href="/2.mp3" singer="任贤齐">沧海一声笑</a> </li> <li data-view="4" class="active"> <a href="/3.mp3" singer="齐秦">往事随风</a> </li> <li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li> <li data-view="5"><a href="/5.mp3" singer="陈慧林">记事本</a></li> <li data-view="5"> <a href="/6.mp3" singer="邓丽君">但愿人长久</a> </li> </ul> </div>''' import re result=re.search('<li.*?active.*?singer="(.*?)">(.*?)</a>',html,re.S) if result: print(result.group(1),result.group(2))
齐秦 往事随风
4.findall
可以返回与正则表达式相匹配的所有字符串
返回结果是列表类型,需要通过遍历来依次获取每组内容
实例
html='''<div id="songs-list"> <h2 class="title">经典老歌</h2> <p class="introduction"> 经典老歌列表 </p> <ul id="list" class="list-group"> <li data-view="2">一路上有你</li> <li data-view="7"> <a href="/2.mp3" singer="任贤齐">沧海一声笑</a> </li> <li data-view="4" class="active"> <a href="/3.mp3" singer="齐秦">往事随风</a> </li> <li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li> <li data-view="5"><a href="/5.mp3" singer="陈慧林">记事本</a></li> <li data-view="5"> <a href="/6.mp3" singer="邓丽君">但愿人长久</a> </li> </ul> </div>''' import re results=re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>',html,re.S) print(results) for result in results: print(result) print(result[0],result[1],result[2])
[('/2.mp3', '任贤齐', '沧海一声笑'), ('/3.mp3', '齐秦', '往事随风'), ('/4.mp3', 'beyond', '光辉岁月'), ('/5.mp3', '陈慧林', '记事本'), ('/6.mp3', '邓丽君', '但愿人长久')] ('/2.mp3', '任贤齐', '沧海一声笑') /2.mp3 任贤齐 沧海一声笑 ('/3.mp3', '齐秦', '往事随风') /3.mp3 齐秦 往事随风 ('/4.mp3', 'beyond', '光辉岁月') /4.mp3 beyond 光辉岁月 ('/5.mp3', '陈慧林', '记事本') /5.mp3 陈慧林 记事本 ('/6.mp3', '邓丽君', '但愿人长久') /6.mp3 邓丽君 但愿人长久
5.sub
re.sub(第一个参数:传入拟匹配的参数,第二个拟替换的参数,第三个参数原字符串)
实例: import re html='''<div id="songs-list"> <h2 class="title">经典老歌</h2> <p class="introduction"> 经典老歌列表 </p> <ul id="list" class="list-group"> <li data-view="2">一路上有你</li> <li data-view="7"> <a href="/2.mp3" singer="任贤齐">沧海一声笑</a> </li> <li data-view="4" class="active"> <a href="/3.mp3" singer="齐秦">往事随风</a> </li> <li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li> <li data-view="5"><a href="/5.mp3" singer="陈慧林">记事本</a></li> <li data-view="5"> <a href="/6.mp3" singer="邓丽君">但愿人长久</a> </li> </ul> </div>''' html=re.sub('<a.*?>|</a>','',html) print(html) results=re.findall('<li.*?>(.*?)</li>',html,re.S) for result in results: print(result.strip())
<div id="songs-list"> <h2 class="title">经典老歌</h2> <p class="introduction"> 经典老歌列表 </p> <ul id="list" class="list-group"> <li data-view="2">一路上有你</li> <li data-view="7"> 沧海一声笑 </li> <li data-view="4" class="active"> 往事随风 </li> <li data-view="6">光辉岁月</li> <li data-view="5">记事本</li> <li data-view="5"> 但愿人长久 </li> </ul> </div> 一路上有你 沧海一声笑 往事随风 光辉岁月 记事本 但愿人长久
6.compile
将正则字符串编译成正则表达式对象,比如:将12:33编译成‘\d{2}:\d{2}'
实例: import re content1='2019-12-5 12:00' content2='2019-12-7 12:55' content3='2012-12-31 13:21' pattern=re.compile('\d{2}:\d{2}') result1=re.sub(pattern,'',content1) result2=re.sub(pattern,'',content2) result3=re.sub(pattern,'',content3) print(result1,result2,result3)
2019-12-5 2019-12-7 2012-12-31
还可以传入修饰符,这样在search和findall中就不需要额外上传了
该方法就是给正则表达式做了一层封装,以便我们更好地复用
2.4httpx
支持HTTP/2.0
1.示例
2.安装
pip3 install "httpx[http2]"
3.基本使用
httpx默认不会开启对HTTP/2.0的支持,需要手动声明才能使用 即:httpx.Clinet(http2=true)
4.Client对象
基本的API与requests中的非常相似,但也有不相似的,如Client,这可与Session类比学习
官方推荐的方式是使用with as语句
示例:import httpx with httpx.Client() as client: response=client.get('https://www.httpbin.org/get') print(response)
子主题
<Response [200 OK]>
等价于:import httpx client=httpx.Client() try: response=client.get('https://www.httpbin.org/get') finally: client.close() print(response)
5.支持HTTP/2.0
httpx默认不会开启对HTTP/2.0的支持,需要手动声明才能使用 即:httpx.Clinet(http2=true)
6.支持异步请求AsyncClient
子主题
子主题
子主题
子主题
子主题
子主题
2.5基础爬虫案例实战
子主题
子主题
子主题
3chapter-Web data extraction
4chapter-Storage of data
5chapter-scrap data of Ajax
6chapter-Asynchronous crawler
7chapter-JavaCrtipt Dynamically render web crawls
8chapter-Verification code identification
9chapter-Use of proxy
10chapter-login simulation
11chapter-Reverse crawler
12chapter-scrap data of App
13chapter-Reverse crawler of Android
14chapter-Page intelligent analysis
15chapter-Use of frame about Scrapy
16chapter-distributed crawling
17chapter-Crawler management and deployment