Python3网络爬虫开发实战(2)爬虫基础库
文章目录
- 一、urllib
- 1. urlparse 实现 URL 的识别和分段
- 2. urlunparse 用于构造 URL
- 3. urljoin 用于两个链接的拼接
- 4. urlencode 将 params 字典序列化为 params 字符串
- 5. parse_qs 和 parse_qsl 用于将 params 字符串反序列化为 params 字典或列表
- 6. quote 和 unquote 对 URL的中文字符进行编码和解码
- 二、requests
- 1. GET 请求
- 2. POST 请求
- 3. Session 维持
- 4. 响应
- 5. 身份认证
- 6. 设置代理
- 7. Prepared Request
- 三、httpx
- 1. Requests Compatibility
- 2. 异步
- 四、基础爬虫实战
一、urllib
urllib 类似于 python 底层构建请求,构建相对于其他的库来说较为复杂,不过 urllib 解析链接非常好用
1. urlparse 实现 URL 的识别和分段
如果需要合并 params 和 query 可以使用 urlsplit
from urllib.parse import urlparseurlparse('https://www.baidu.com/')# ParseResult(scheme='https', netloc='[www.baidu.com](https://www.baidu.com/)', path='/', params='', query='', fragment='')
2. urlunparse 用于构造 URL
urlunparse 这个方法接收的参数是一个可迭代对象,且其长度必须为 6;同样的,如果需要合并 params 和 query 可以使用 urlunsplit
from urllib.parse import urlunparsedata = ['https','www.baidu.com','index.html','user','a=6','comment']urlunparse(data)
# https://www.baidu.com/index.html;user?a=6#comment
3. urljoin 用于两个链接的拼接
urljoin 首先会解析 new_url,判断其 scheme,netloc,path 是否出现了缺失,如果确实使用 base_url 中的 scheme,netloc,path 对应缺失部分代替;
from urllib.parse import urljoinbase_url = 'https://www.baidu.com'
new_url = 'FAQ.html'urljoin(base_url, new_url)
# https://www.baidu.com/FAQ.html
4. urlencode 将 params 字典序列化为 params 字符串
from urllib.parse import urlencodeparams = {'name': 'germey','age': 2,
}base_url = 'https://www.baidu.com?'
base_url + urlencode(params)
# https://www.baidu.com?name=germey&age=2
5. parse_qs 和 parse_qsl 用于将 params 字符串反序列化为 params 字典或列表
from urllib.parse import parse_qs, parse_qslparams = 'name=germey&age=25'parse_qs(params, separator='&')
# {'name': ['germey'], 'age': ['25']}parse_qsl(params, separator='&')
[('name', 'germey'), ('age', '25')]
6. quote 和 unquote 对 URL的中文字符进行编码和解码
from urllib.parse import quote, unquoteurl = "https://www.baidu.com/s?wd=爬虫"# utf8编码,指定安全字符
quote(url, safe=";/?:@&=+$,", encoding="utf-8")
# https://www.baidu.com/s?wd=%E7%88%AC%E8%99%AB# gbk编码,指定安全字符
quote(url, safe=";/?:@&=+$,", encoding="gbk")
# https://www.baidu.com/s?wd=%C5%C0%B3%E6# utf8解码
unquote('https://www.baidu.com/s?wd=%E7%88%AC%E8%99%AB', encoding='utf-8')
# https://www.baidu.com/s?wd=爬虫# gbk解码
unquote('https://www.baidu.com/s?wd=%C5%C0%B3%E6', encoding='gbk')
# https://www.baidu.com/s?wd=爬虫
二、requests
1. GET 请求
测试 URL: www.httpbin.org/get
cookies 可以单独设置,也可以放在 headers 的 cookie 字段下传入请求之中,timeout 可以控制超时时间,headers 是请求头,params 是参数构建完整的 url;
import requestsparams = {}
headers = {}
cookies = {}# vertify 设置为 False 可以避免 ssl 认证
requests.get(url=url, params=params, headers=headers, cookies=cookies, vertify=False, timeout=None)
2. POST 请求
测试 URL: www.httpbin.org/post
POST 是上传东西的常用请求,POST 请求中除了 GET 请求中的那些参数,还有一些参数可以使用,如 data 和 file;其中 data 主要用来传表单,而 file 主要用来传文件;
import requestsparams = {}
headers = {}
cookies = {}data = {}
file = {}# vertify 设置为 False 可以避免 ssl 认证
requests.post(url=url, params=params, headers=headers, cookies=cookies, vertify=False, timeout=None, data=data, file=file)
3. Session 维持
多次直接利用 requests 库中的 get 或 post 方法模拟网络请求,相当于打开了多个不同的浏览器,而使用 Session 维持 搭配 get 和 post 方法去模拟网络请求,相当于打开了一个浏览器中的多个页面;
import requestss = requests.Session(headers=headers)
s.get(url_1)
s.get(url_2)# 这里在第一次 get 请求中获得到的 cookie 就会保持进而在第二次 get 请求中得到
4. 响应
import requestsresp = requests.get()# 状态码
resp.status_code# 响应头
resp.headers# cookies
resp.cookies# 最终 url 搭配重定向使用 requests.get(url, allow_redirects=False)
resp.url# 请求历史
resp.history# 在获取 resp.text 先配置 encoding
resp.encoding# 响应结果字符串形式,需要搭配 resp.encoding = 'utf-8' or 'gbk' 使用
resp.text# 二进制相应结果,通常对应于文件
resp.content# resp.text 转化为 json 数据,如果不是json 数据格式,则会出现解析错误,抛出 json.decoder.JSONDecodeError 异常
resp.json
5. 身份认证
在访问启用了基本身份认证的网站时,首先会弹出一个认证窗口,认证正确会弹出 200状态码,如果认证错误或者不进行认证会弹出 401 错误;
import requests
from requests.auth import HTTPBasicAuth# 第一行是第二行的简写
r = requests.get('https://ssr3.scrape.center/',auth=('admin','admin'))
r = requests.get('https://ssr3.scrape.center/',auth=HTTPBasicAuth('admin','admin'))r.status_code
# 200
requests 库还提供了其他的认证方式,如 OAuth 认证,需要安装 oauth 包;
6. 设置代理
首先是基本的 HTTP 代理
import requestsproxies = {'http':'http://10.10.10,10:1080','https':'https://10.10.10.10:1080',
}requests.get('https://www.httpbin.org/get', proxies=proxies)
除了基本的 HTTP 代理外,还支持 SOCKS 协议的代理,首先需要安装 socks 库 pip install requests[socks]
import requestsproxies = {'http':'socks5://10.10.10,10:1080','https':'socks5://10.10.10.10:1080',
}requests.get('https://www.httpbin.org/get', proxies=proxies)
7. Prepared Request
因此多个 get 或者 post 请求相当于多个 Session,尽量避免对同一网页使用多个 get 或者 post 请求
from requests import Request,Sessionurl = 'https://www.httpbin.org/post'
data = {'name':'germey'}
headers = {}# 请求的底层
s = Session()
req = Request('POST', url, data=data, headers=headers)
prepped = s.prepare_request(req)
r = s.send(prepped)# 等价
r = requests.post(url, data=data, headers=headers)
三、httpx
HTTPX 建立在 requests
完善的可用性之上,支持 HTTP/2 并支持异步;HTTPX (python-httpx.org)
可选安装如下:
h2
- HTTP/2 支持。 (可选,带有httpx[http2]
)socksio
- SOCKS 代理支持。 (可选,带有httpx[socks]
)brotli
或brotlicffi
- 解码“brotli”压缩响应。 (可选,带有httpx[brotli]
)
HTTPX 与 requests 的 API 广泛兼容,在少部分地方存在一些设计差异:Requests Compatibility - HTTPX (python-httpx.org)
1. Requests Compatibility
重定向:与 requests 不同,HTTPX 默认情况下是不遵循 重定向 (redirects) 的,开启重定向如下所示
client = httpx.Client(follow_redirects=True)
response = client.get(url, follow_redirects=True)
Client:等价于 requests.Session 维持,即等价
session = requests.Session(**kwargs)
client = httpx.Client(**kwargs)
URL:访问 response.url 将返回 url 实例,requests 返回的是字符串
重定向请求:requests
库公开了一个属性 response.next
,该属性可用于获取下一个重定向请求。在 HTTPX 中,此属性被命名为 response.next_request
。
# requests
session = requests.Session()
request = requests.Request("GET", ...).prepare()
while request is not None:response = session.send(request, allow_redirects=False)request = response.next# httpx
client = httpx.Client()
request = client.build_request("GET", ...)
while request is not None:response = client.send(request)request = response.next_request
请求内容:对于上传原始文本或二进制内容,httpx 使用 content
参数,以便更好地将这种用法与上传表单数据的情况分开。使用 content=...
上传原始内容,并使用 data=...
发送表单数据;
httpx.post(..., content=b"Hello, world")
httpx.post(..., data={"message": "Hello, world"})
上传文件:HTTPX 严格强制上传文件必须以二进制模式打开,以避免尝试上传以文本模式打开的文件可能导致的字符编码问题。
内容编码:HTTPX 使用 utf-8
来编码 str
请求正文。例如,当使用 content=<str>
时,请求正文将在通过线路发送之前编码为 utf-8
。
Cookie
,trust_env
、 verify
和 cert
参数:如果使用客户端实例,应始终在客户端实例化时传递,而不是传递给请求方法。
2. 异步
requests 是不支持异步的,通常我们会使用 aiohttp 来进行异步操作,而 httpx 不仅支持同步还支持异步
import asyncio
import httpxasync def main():async with httpx.AsyncClient() as client:response = await client.get('https://www.example.com/')print(response)asyncio.run(main())
四、基础爬虫实战
任务:
- 使用爬虫基本库爬取 https://ssr1.scrape.center/ 每一页的电影列表,顺着列表再爬取每个电影的详细页
- 使用正则表达式提取每部电影的名称,封面,类别,上映时间,剧情简介等内容;
- 使用多进程实现爬取的加速;
流程:

代码:
import os
import re
import httpx
import json
from multiprocessing import Pool
from urllib.parse import urljoinbase_url = "https://ssr1.scrape.center"def scrape_index(page):"""获得page的url"""page_url = f"{base_url}/page/{page}"return page_urldef scrape_list(html):"""获得列表的url"""url_list = re.findall(r'<a data.* href="(.*)" class="name">', html)url_list = [urljoin(base_url, item) for item in url_list]return url_listdef scrape_detail(html):"""获得详细页信息"""detail_dic = {}detail_dic["名称"] = (re.search(r'<h2 data.*? class="m-b-sm">(.*?)</h2>', html, re.S).group(1)if re.search(r'<h2 data.*? class="m-b-sm">(.*?)</h2>', html, re.S)else None)detail_dic["封面"] = (re.search(r'class="item.*?<img.*?src="(.*?)".*?class="cover">', html, re.S).group(1)if re.search(r'class="item.*?<img.*?src="(.*?)".*?class="cover">', html, re.S)else None)detail_dic["类别"] = re.findall(r"<button.*?category.*?<span>(.*?)</span>.*?</button>", html, re.S)detail_dic["上映时间"] = (re.search(r"<span>.*?(\d{4}-\d{2}-\d{2}) 上映", html, re.S).group(1)if re.search(r"<span>.*?(\d{4}-\d{2}-\d{2}) 上映", html, re.S)else None)detail_dic["剧情简介"] = (re.search(r"剧情简介</h3>.*?<p.*?>(.*?)</p>", html, re.S).group(1).strip()if re.search(r"剧情简介</h3>.*?<p.*?>(.*?)</p>", html, re.S)else None)return detail_dicdef validateTitle(title):"""命名规范性"""rstr = r"[\/\\\:\*\?\"\<\>\|]" # '/ \ : * ? " < > |'new_title = re.sub(rstr, "_", title) # 替换为下划线return new_titledef save_json(detail_dic):"""保存数据到json文件夹下"""os.makedirs("./json", exist_ok=True)name = detail_dic["名称"]data_path = f"./json/{validateTitle(name)}.json"json.dump(detail_dic, open(data_path, "w", encoding="utf-8"), ensure_ascii=False, indent=2)def main(page):client = httpx.Client()page_url = scrape_index(page)resp_page = client.get(page_url).texturl_list = scrape_list(resp_page)for detail_url in url_list:resp_detail = client.get(detail_url).textdetail_dic = scrape_detail(resp_detail)save_json(detail_dic)if __name__ == "__main__":pool = Pool(10)pages = range(1, 10 + 1)pool.map(main, pages)pool.close()pool.join()
得到结果如下:

相关文章:

Python3网络爬虫开发实战(2)爬虫基础库
文章目录 一、urllib1. urlparse 实现 URL 的识别和分段2. urlunparse 用于构造 URL3. urljoin 用于两个链接的拼接4. urlencode 将 params 字典序列化为 params 字符串5. parse_qs 和 parse_qsl 用于将 params 字符串反序列化为 params 字典或列表6. quote 和 unquote 对 URL的…...

el-image预览图片点击遮盖处关闭预览
预览关闭按钮不明显 解决方式: 1.修改按钮样式明显点: //el-image 添加自定义类名,下文【test-image】代指 .test-image .el-icon-circle-close{ color:#fff; font-size:20px; ...改成很明显的样式 }2.使用事件监听,监听当前遮…...

基于Neo4j将知识图谱用于检索增强生成:Knowledge Graphs for RAG
Knowledge Graphs for RAG 本文是学习https://www.deeplearning.ai/short-courses/knowledge-graphs-rag/这门课的学习笔记。 What you’ll learn in this course Knowledge graphs are used in development to structure complex data relationships, drive intelligent sea…...

康康近期的慢SQL(oracle vs 达梦)
近期执行的sql,哪些比较慢? 或者健康检查时搂一眼状态 oracle: --最近3天内的慢sql set lines 200 pages 100 col txt for a65 col sql_id for a13 select a.sql_id,a.cnt,a.pctload,b.sql_text txt from (select * from (select sql_id,co…...

探索 GPT-4o mini:成本效益与创新的双重驱动
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

2.6基本算法之动态规划2989:糖果
描述 由于在维护世界和平的事务中做出巨大贡献,Dzx被赠予糖果公司2010年5月23日当天无限量糖果免费优惠券。在这一天,Dzx可以从糖果公司的N件产品中任意选择若干件带回家享用。糖果公司的N件产品每件都包含数量不同的糖果。Dzx希望他选择的产品包含的糖…...

12.顶部带三角形的边框 CSS 关键字 currentColor
顶部带三角形的边框 创建一个在顶部带有三角形的内容容器。 使用 ::before 和 ::after 伪元素创建两个三角形。两个三角形的颜色应分别与容器的 border-color 和容器的 background-color 相同。一个三角形(::before)的 border-width 应比另一个(::after)宽 1px,以起到边框的作…...

Llama中模块参数大小
LLama2中,流程中数据大小的变换如下 Transformer模块 第一次输入,进行prefill,输入x维度为[1, 8, 4096] 1. 构建wq,wk,wv,wo,尺寸均为[4096,4096], 与x点乘,得到xq, xk, xv 2. 构建KV cache, 尺寸为 [b…...

Modbus转EtherCAT网关将Modbus协议的数据格式转换为EtherCAT协议
随着工业自动化技术的快速发展,不同通信协议之间的互操作性变得越来越重要。Modbus作为一种广泛使用的串行通信协议,与以太网为基础的EtherCAT协议之间的转换需求日益增长。本文将从网关功能、硬件设计、性能以及应用案例来介绍这款Modbus转EtherCAT网关…...

【开发实战】QT5 + OpenCV4 开发环境配置应用演示
前言 作为深度学习算法工程师,必须要掌握应用开发技能吗?搞工程肯定是必须要会界面开发,QT就是一个很不错的选择。本文以QT5.15 OpenCV4.8 OpenVINO2023为例,搭建应用开发环境,演示深度学习模型的QT应用案例。 开发…...

“微软蓝屏”事件暴露的网络安全问题及应对策略
“微软蓝屏”事件暴露了网络安全哪些问题? 近日,一次由微软视窗系统软件更新引发的全球性“微软蓝屏”事件,不仅成为科技领域的热点新闻,更是一次对全球IT基础设施韧性与安全性的深刻检验。这次事件,源于美国电脑安全技…...

白骑士的PyCharm教学基础篇 1.3 调试与运行
系列目录 上一篇:白骑士的PyCharm教学基础篇 1.2 PyCharm基本操作 配置与调试环境 配置调试环境 选择解释器 在 PyCharm 中选择正确的 Python 解释器:依次点击 “File” -> “Settings” -> “Project: [项目名]” -> “Project Interpret…...

爬虫学习1:初学者简单了解爬虫的基本认识和操作(详细参考图片)
爬虫 定义:爬虫(Web Crawler 或 Spider)是一种自动访问互联网上网页的程序,其主要目的是索引网页内容,以便搜索引擎能够快速检索到相关信息。以下是爬虫的一些关键特性和功能: 自动化访问:爬虫能…...

WHAT - 通过 shadcn 组件源码学习 React
目录 一、button1. 导入部分2. 定义按钮的样式变体1. variant2. size总结 3. 定义按钮的属性类型4. 定义按钮组件5. 导出组件和样式变体总结 二、multi-select多选组件的核心上下文与状态1. 上下文与钩子2. MultiSelector 组件 组件子部分1. MultiSelectorTrigger2. MultiSelec…...

grafana对接zabbix数据展示
目录 1、初始化、安装grafana 2、浏览器访问 3、安装zabbix 4、zabbix数据对接grafana 5、如何导入模板? ① 设置键值 ② 在zabbix web端完成自定义监控项 ③ garafana里添加nginx上面的的三个监控项 6、如何自定义监控项? 以下实验沿用上一篇z…...

C++ 学习补充 1:短链算法
短链算法 短链算法: 将长链接 转化为 一个短key 之所以不是短url 是因为 ,url 短链不区分大小写,可用空间比较小。 短链算法通常用于将一个长网址转换成一个较短的字符串,以便于分享和存储。这种算法通常需要满足以下条件&#…...

硅纪元视角 | 语音克隆突破:微软VALL-E 2,Deepfake新纪元!
在数字化浪潮的推动下,人工智能(AI)正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展,捕捉行业动态;提供深入的新闻解读,助您洞悉技术背后的逻辑;汇聚行业专家的见解,…...

没有51基础,能不能学好STM32?
在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「STM32的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!! 我们通常准备攻读一本大部…...

Web开发:VUE3小白开发入门基础笔记
一、基本语法 1.click 后端路由:api/GetDataList 返回值:Value 前端要做的事: ①拿到Value值,传到a标签 ②a标签有一个按钮,每点击一下,Value的值加一。 前端需要用click语法 【代码】 <template>…...

技术周总结 2024.07.15~07.21周日(Spark性能优化)
文章目录 一、07.19 周五1.1)问题01: spark性能优化1.2)问题02: spark是怎么应用在机器学习领域的1.3)问题03:spark自带工具有哪些?1.4)问题04: spark日志的知识点有哪些…...

提高性能的常见技术
1.数据库层面: 读写分离,对于大部分业务来说,读取操作要大于写入,同一个库,既读又写的话,负载会比较重,拆分为读库和写入库,可以降低数据库的负载,分时或延迟将写入的数…...

LeetCode206 反转链表
前言 题目: 206. 反转链表 文档: 代码随想录——反转链表 编程语言: C 解题状态: 有了思路以后没敢尝试 思路 需要注意的是创建指针不会申请额外的内存空间。 代码 方法一: 双指针法/迭代 我的理解是创建了三个指针…...

nginx通过nginx_upstream_check_module实现后端健康检查
1、简介说明 nginx是常用的反向代理和负载均衡服务,具有强大并发能力、稳定性、丰富的功能集、低资源的消耗。 nginx自身是没有针对后端节点健康检查的,但是可以通过默认自带的ngx_http_proxy_module 模块和ngx_http_upstream_module模块中的相关指令来完…...

FastGPT 知识库搜索测试功能解析(二)
目录 一、代码解析 1.1 searchTest.ts 1.2 controller.ts 本文接上一篇文章FastGPT 知识库搜索测试功能解析 对具体代码进行解析。 一、代码解析 FastGPT 知识库的搜索测试功能主要涉及两个文件,分别是 searchTest.ts 和 controller.ts 文件,下面分别进行介绍。 1.1 se…...

双向链表<数据结构 C版>
目录 关于链表的分类 双向链表结构体 初始化 尾插 头插 打印 判断是否为空 尾删 头删 查找 指定位置之后的插入 指定位置的删除 销毁 关于链表的分类 根据链表的三大特性,单向or双向、带头or不带头、循环or不循环,可将链表分为2*2*2…...

react18+
主要是围绕函数式组件讲,18主要用就是函数式组件,学习前先熟悉下原生js的基本使用,主要是事件 1、UI操作 1.1、书写jsx标签语言 基本写法和原生如同一则,只是放在一个方法里面返回而已,我们称这样的写法为函数式组件…...

rk3568 OpenHarmony4.1 Launcher定制开发—桌面壁纸替换
Launcher 作为系统人机交互的首要入口,提供应用图标的显示、点击启动、卸载应用,并提供桌面布局设置以及最近任务管理等功能。本文将介绍如何使用Deveco Studio进行单独launcher定制开发、然后编译并下载到开发板,以通过Launcher修改桌面背景…...

MySQL:送分or送命 varchar(30) 与 int(10)
摘要: VARCHAR(30) 和 INT(10) 在MySQL中代表两种不同类型的字段,它们之间的主要区别在于它们存储的数据类型、存储方式以及显示宽度的含义。 正文: INT(10) 在MySQL中,当你看到INT(10)这样的数据类型定义时,可能会…...

【odoo17】后端py方法触发右上角提示组件
概要 在前面文章中,有介绍过前端触发的通知服务。 【odoo】右上角的提示(通知服务) 此文章则介绍后端触发方法。 内容 直接上代码:但是前提一定是按钮触发!!!!! def bu…...

1775D - Friendly Spiders
题目链接:Friendly Spiders 首先我们可以考虑暴力做法,那就是每两个蜘蛛判断一下gcd,如果不等于1,那就连条边,这样的话时间复杂度是O(n^2),显然超时,因此我们可以采用类似…...