文章

Python 首批细教程 · 05A:别一上来就爬站,先把 requests、XPath、BS4 这条链跑通

#273 · 2026-05-13 · Python 教程拆解

对应原仓库62.用Python获取网络资源-1.md62.用Python解析HTML页面-2.md

已提供可运行示例/tutorial-assets/python-100-days/05a-requests-parse-stack/(站点源码路径:blog-src/static/tutorial-assets/python-100-days/05a-requests-parse-stack/

这一篇只解决一件事:把“获取”和“解析”分开练清楚。

Step 1:最小 requests

import requests

resp = requests.get("https://httpbin.org/html", timeout=10)
print(resp.status_code)
print(resp.text[:120])

这一步只回答一个问题:你能不能把内容先拿回来。

Step 2:本地 HTML + XPath

示例目录已经提供 sample.html(站点源码路径:blog-src/static/tutorial-assets/python-100-days/05a-requests-parse-stack/sample.html):

<html>
  <body>
    <ul id="books">
      <li><span class="title">Python</span><span class="price">59</span></li>
      <li><span class="title">FastAPI</span><span class="price">88</span></li>
    </ul>
  </body>
</html>

示例目录已经提供 xpath_demo.py(站点源码路径:blog-src/static/tutorial-assets/python-100-days/05a-requests-parse-stack/xpath_demo.py):

from lxml import etree
from pathlib import Path

html = Path("sample.html").read_text(encoding="utf-8")
tree = etree.HTML(html)

titles = tree.xpath('//*[@id="books"]/li/span[@class="title"]/text()')
prices = tree.xpath('//*[@id="books"]/li/span[@class="price"]/text()')

for title, price in zip(titles, prices):
    print(title, price)

安装依赖:

pip install lxml

Step 3:再练 BeautifulSoup / CSS 选择器

示例目录已经提供 bs4_demo.py(站点源码路径:blog-src/static/tutorial-assets/python-100-days/05a-requests-parse-stack/bs4_demo.py):

from pathlib import Path
from bs4 import BeautifulSoup

html = Path("sample.html").read_text(encoding="utf-8")
soup = BeautifulSoup(html, "lxml")

titles = soup.select("#books .title")
prices = soup.select("#books .price")

for title, price in zip(titles, prices):
    print(title.text, price.text)

安装:

pip install beautifulsoup4 lxml

三者到底怎么分工

工具 作用
requests 把内容拿回来
XPath 按树结构精确提取
BS4/CSS 选择器 用更友好的方式定位元素

这就是原仓库 Day62 最值得学透的地方。

进阶任务

  1. sample.html 再加一列作者。
  2. 用 XPath 提取作者。
  3. 用 BS4 重写同样逻辑。

常见坑

  • 还没拿到内容就开始调解析器。
  • XPath 路径写死得过于脆弱。
  • BS4 选择器写错却以为页面没数据。