import requests from bs4 import BeautifulSoup url='www.cdsf.org.cn/' s=requests.Session() s.trust_env=False html=s.get(url).text soup=BeautifulSoup(html) print(soup.title.string)
ChatGPT 说:
已思考 8s
燎然,这样有时能跑,但不稳,主要有 4 个坑:
-
没 UA:不少站看到
python-requests会给“瘦页面”或直接拦。 -
没超时:默认无限等,卡住你不知道。
-
没指定解析器:
BeautifulSoup(html)会猜解析器,容易出警告/不一致;建议显式"html.parser"(或安装lxml后用它)。 -
直接
.title.string:只在<title>只有“单一纯文本子节点”时才有值,否则就是None;稳妥写法用get_text()并先判空。
最小改动版(在你代码上修一下就行)
import requests
from bs4 import BeautifulSoup
url = "https://www.cdsf.org.cn/"
HEADERS = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/139.0 Safari/537.36"
)
}
s = requests.Session()
s.trust_env = False # 不继承系统代理
r = s.get(url, headers=HEADERS, timeout=(6,15), allow_redirects=True)
r.raise_for_status()
# 编码兜底(很多中文站声明不准)
if r.apparent_encoding and (not r.encoding or r.encoding.lower() == "iso-8859-1"):
r.encoding = r.apparent_encoding
soup = BeautifulSoup(r.text, "html.parser") # 显式解析器
title_tag = soup.find("title")
print(title_tag.get_text(strip=True) if title_tag else "未找到标题")
为啥你那段可能“看起来能跑”
-
有的网站刚好不拦 UA、编码也正常、页面有标准
<title>,所以你能打印出标题; -
但一旦遇到编码写错、风控或
<title>内混了子标签,你的代码就会翻车(None或乱码)。
小技巧(排错时很有用)
print(r.status_code, r.url, r.encoding) # 看状态/跳转/编码
print(len(r.text)) # 页面很短多半是“瘦页面”
照这版改,你这一步就稳了。接下来我们可以把“标题解析”扩成:优先 <title> → og:title → twitter:title → <h1>,命中率更高。继续冲!💪
您说:
html.parser 是什么
ChatGPT 说:
已思考 10s
"html.parser" 是 BeautifulSoup 使用的解析器名称,表示用 Python 标准库自带的 HTML 解析器来把一段 HTML 字符串“拆解 → 建树(DOM)”。有了树结构,你就能 find / select / get_text 去定位元素、拿文本和属性。
和其它解析器怎么选?
常见 3 个选项(把第二个参数换掉就行):
-
"html.parser"(你现在用的)-
优点:零依赖、安装最省事、稳定性尚可。
-
缺点:速度和容错性一般,遇到很烂的 HTML 可能还原不完整。
-
-
"lxml"(推荐)-
优点:最快、容错也强,解析结果稳定。
-
缺点:需要安装
lxml(pip install lxml),首次装略慢。
-
-
"html5lib"-
优点:容错最强,按浏览器 HTML5 规范修树,烂页面也能还原。
-
缺点:最慢,还需安装
html5lib。
-
代码示例
from bs4 import BeautifulSoup
# 显式指定解析器(建议总是显式)
soup = BeautifulSoup(html, "html.parser") # 零依赖
# soup = BeautifulSoup(html, "lxml") # pip install lxml
# soup = BeautifulSoup(html, "html5lib") # pip install html5lib
自动优先用 lxml,缺了就退回 html.parser
from bs4 import BeautifulSoup
try:
import lxml # 只为检测是否安装
PARSER = "lxml"
except Exception:
PARSER = "html.parser"
soup = BeautifulSoup(html, PARSER)
实战建议(给你当前项目)
-
先
pip install lxml,把解析器切到"lxml",你的爬虫会更快更稳。 -
遇到“瘦页面/烂 HTML”解析不出结构,再临时切
"html5lib"尝试。 -
一定显式指定解析器:不同环境的默认值可能不同,显式能避免不可预期差异。
一句话记忆:
html.parser = 自带解析器,够用但一般 → 优先用 lxml,必要时 html5lib 救场。
您说:
import requests from bs4 import BeautifulSoup url='www.cdsf.org.cn/' s=requests.Session() s.trust_env=False r=s.get(url,timeout(4,10)).text soup=BeautifulSoup(r,"html.parser") print(soup.title.string)
ChatGPT 说:
已思考 26s
燎然,你这段报错的核心是这行写错了:
r = s.get(url,timeout(4,10)).text
timeout(4,10) 像是在“调用一个名为 timeout 的函数”,而不是把 timeout 参数 传给 get。正确写法是关键字参数:
最小修复版(直接能跑)
import requests
from bs4 import BeautifulSoup
url = "https://www.cdsf.org.cn/"
s = requests.Session()
s.trust_env = False
resp = s.get(url, timeout=(4, 10)) # ✅ 用等号,(连接超时, 读取超时)
resp.raise_for_status()
soup = BeautifulSoup(resp.text, "html.parser")
print(soup.title.get_text(strip=True) if soup.title else "未找到标题")
建议的稳健版(加 UA + 编码兜底)
import requests
from bs4 import BeautifulSoup
url = "https://www.cdsf.org.cn/"
HEADERS = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/139.0 Safari/537.36"
)
}
with requests.Session() as s:
s.trust_env = False
r = s.get(url, headers=HEADERS, timeout=(4,10), allow_redirects=True)
r.raise_for_status()
# 编码兜底(很多中文站写成 ISO-8859-1)
if r.apparent_encoding and (not r.encoding or r.encoding.lower() == "iso-8859-1"):
r.encoding = r.apparent_encoding
soup = BeautifulSoup(r.text, "html.parser")
print(soup.title.get_text(strip=True) if soup.title else "未找到标题")