python爬取网站源码

 人参与 | 时间:2026-10-17 07:09:01

用 Python 拿网站源码,网站最直接的源码办法就是 requests.get()。三行代码能跑通的网站事,很多人却卡在第一步——被网站识别成爬虫,源码返回 403。网站我上周抓一个博客站,源码浏览器打开一切正常,网站requests 过去直接吃闭门羹。源码问题不在代码,网站在于请求头太干净了。源码

默认的网站 User-Agent 是 python-requests/2.x,等于举着牌子告诉服务器“我是源码脚本”。加一个浏览器 UA 就能解决大半问题:

import requests headers = {  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML,网站 like Gecko) " "Chrome/120.0.0.0 Safari/537.36" } resp = requests.get("https://example.com", headers=headers, timeout=10) resp.encoding = resp.apparent_encoding print(resp.text[:500]) 

resp.text 拿到的是解码后的字符串,resp.content 是源码原始字节。中文站经常乱码,网站因为服务器没声明编码或者声明错了。apparent_encoding 用 chardet 猜编码,比自己写 resp.encoding = 'utf-8' 靠谱。我碰到过一个 GBK 站,requests 默认按 ISO-8859-1 解,满屏问号,换成 apparent_encoding 立刻正常。

有些页面源码是 JS 渲染出来的,requests 拿到的 HTML 里只有一堆 <div id="app"></div>,真正的内容在接口返回的 JSON 里。这时候别硬爬 HTML,打开浏览器开发者工具的 Network 面板,找 XHR 请求,直接请求那个接口。我抓一个电商列表页,HTML 里商品信息全是空的,接口 /api/goods/list?page=1 返回的 JSON 结构清清楚楚,省了解析 DOM 的功夫。

如果接口有签名或者加密参数,那就得上 Selenium 或 Playwright。Selenium 启动一个真实浏览器,等页面加载完再 driver.page_source,拿到的就是渲染后的完整源码。代价是慢,一个页面几秒钟,还得配 chromedriver。Playwright 更快一些,API 也更现代,page.content() 一行搞定。我一般先用 requests 试,碰壁了再换 Playwright,不轻易上重型武器。

反爬不只是 UA。有的站检查 Referer,有的检查 Cookie,还有的用 Cloudflare 做 JS 挑战。Cloudflare 那种五秒盾,requests 基本没戏,得用 cloudscraper 库或者直接上浏览器。我试过 cloudscraper 抓一个 CF 保护的论坛,成功率大概七成,偶尔还是被拦。后来换成 Playwright 加 stealth 插件,稳定多了。

拿到源码之后,解析用 BeautifulSoup 还是 lxml 看个人习惯。BeautifulSoup 容错好,写起来舒服;lxml 快,XPath 表达力强。我一般 BeautifulSoup(resp.text, 'lxml'),兼顾两者。找元素用 soup.select('.title a') 这种 CSS 选择器,比 find_all 层层嵌套直观。

频率控制别忽视。我见过有人写个 for 循环不带 sleep,一秒请求几十次,IP 被封了还纳闷。加个 time.sleep(random.uniform(1, 3)),模拟人类节奏。真要大量抓,上代理池,但那是另一个话题了。

最后提一句法律边界。爬公开数据做个人分析,一般没人管。绕过登录、抓别人付费内容、高频请求搞崩服务器,那就不是技术问题了。我自己的原则是:只抓看得见的、不碰需要授权的、控制频率别给人添麻烦。

顶: 2813踩: 412