使用Python程序获取网站内容
Python网页抓取程序下载HTML并提取所选元素。BeautifulSoup将标记转换为可搜索的标签、属性、文本和链接树。工作流程为:请求、验证、解析、选择和保存。在web.run中,Python通过Pyodide运行,因此网络活动和加载的包也会显示在Run Details中。
Python程序抓取网站HTML示例
输出:
输出将显示在这里...
输出:
Title: Header
Links found: 9
示例工作原理
pyfetch发送异步请求,因此程序在顶层使用await。- 状态检查防止错误页面被解析为目标文档。
response.string()读取响应体,BeautifulSoup使用html.parser进行解析。find("h1")返回第一个标题,而find_all("a")返回所有链接。
使用Run Details检查抓取器
程序完成后打开Run Details。它将抓取器发出的页面请求与执行代码所需的包活动分开显示。
| Run Details信号 | 含义 |
|---|---|
| Requests显示对raw.githubusercontent.com的GET请求 | 抓取器尝试下载HTML文件 |
| 请求状态为200 | 浏览器成功接收到页面 |
| 请求失败或被阻止 | 检查连接以及目标是否允许来自浏览器的跨域请求 |
| Packages列出beautifulsoup4 | web.run检测到bs4导入并加载了支持的包 |
| 状态200但提取的值缺失 | 网络正常;检查HTML和选择器 |
请求旁边的时间测量页面获取时间;总时间还包括包加载、解析和Python执行。BeautifulSoup通常在首次运行时下载,然后在当前运行时中保持可用,因此后续运行可能更快完成,并且不显示新的包活动。
如何用Python抓取网站
- 选择一个允许自动访问和浏览器请求的页面。
- 下载HTML,并在解析之前拒绝非成功的HTTP状态码。
- 从响应体创建一个BeautifulSoup对象。
- 检查标记,通过语义标签、属性或CSS选择器选取元素。
- 在保存结果之前,规范化提取的文本并将相对URL转换为绝对URL。
更多Python BeautifulSoup示例
提取所有章节标题
使用一个CSS选择器收集多个标题级别:
for heading in soup.select("h2, h3"):
print(heading.get_text(" ", strip=True))
分隔符使嵌套标签中的文本保持分离,而strip=True删除周围的空白字符。
提取并规范化链接
将绝对链接、相对链接和片段链接解析为页面URL:
from urllib.parse import urljoin
for link in soup.select("a[href]"):
print(urljoin(url, link["href"]))
[href]选择器排除没有目标的锚点,使属性访问更安全。
选择BeautifulSoup选择器
| 任务 | 选择器 | 结果 |
|---|---|---|
| 页面第一个标题 | soup.find("h1") | 一个标签或None |
| 所有链接 | soup.find_all("a") | 标签列表 |
| 有目标的链接 | soup.select("a[href]") | 匹配CSS选择器的标签 |
| 文章内的元素 | soup.select("article .item") | 仅匹配的后代 |
当期望单个元素时使用find,基于标签的集合使用find_all,当关系或属性使CSS选择器更清晰时使用select。
Python网页抓取常见问题
- 并非所有URL都可访问。Pyodide在浏览器中运行,因此页面可以在标签页中打开,但可能拒绝来自web.run的跨域请求。
- 缺失的元素需要明确检查。当选择器没有匹配时,BeautifulSoup返回
None;立即访问其文本会引发错误。 - JavaScript生成的内容不在下载的HTML中。BeautifulSoup解析服务器响应但不执行脚本;当选择器没有返回匹配时,请检查响应体。
遵守爬取规则,限制请求频率,缓存未变更的页面,并在服务器报告请求过多时降低负载。
有关周围的控制流,请参阅Python异常处理和Python条件判断。
FAQ
Python网页抓取使用哪个库?
BeautifulSoup解析和查询下载的HTML。pyfetch等网络客户端获取文档,而BeautifulSoup通过标签、属性或CSS选择器选取元素。
BeautifulSoup能抓取JavaScript网站吗?
BeautifulSoup解析服务器提供的HTML,但不执行JavaScript。仅在脚本执行后创建的元素不会出现在解析后的文档中。