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日志的知识点有哪些…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
