游客发表

爬虫技术抓取网站数据代码

发帖时间:2026-10-17 04:48:18

用 requests + BeautifulSoup 抓豆瓣电影 Top250,爬虫核心代码不超过 20 行。技术但真正跑起来,网站你会发现第 3 页开始返回 418,数据连数据影子都见不着。代码这不是爬虫代码写错了,是技术网站知道你不是人。

我上周帮朋友抓某招聘网站的网站岗位信息。第一页 60 条数据顺利拿到,数据第二页直接跳验证码。代码换了个思路,爬虫把请求头里的技术 User-Agent 改成正常浏览器标识,加了个 1 秒的网站延时,再跑——又拿到 60 条。数据第三页再次被拦。代码这说明什么?对方不是靠单一规则判断,而是综合请求频率、header 完整度、甚至鼠标行为来打分。

最简爬虫长什么样

先看能跑通的基础代码:

import requests from bs4 import BeautifulSoup url = "https://example.com/list?page=1" headers = {  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } resp = requests.get(url, headers=headers, timeout=10) soup = BeautifulSoup(resp.text, "html.parser") for item in soup.select(".item-title"): print(item.get_text(strip=True))

这段代码能抓静态页面。但现在的网站,列表数据多数走 XHR 接口,HTML 里根本没有。你右键查看源代码,发现全是空的 div,数据是 JS 渲染出来的。这时候 BeautifulSoup 拿到的只是一副骨架。

绕不开的反爬三件事

第一,请求头要像真人。Accept、Accept-Language、Referer 这些字段缺一两个,对方风控系统就给你扣分。我习惯直接复制浏览器开发者工具里“Copy as cURL”的完整头信息,粘进代码里改。

第二,IP 不能太集中。同一 IP 连续请求 50 次以上,很多站点就开始限速。免费代理池质量参差不齐,10 个里能用的不到 2 个。付费代理稳定些,但成本摆在那。小规模抓取,加个 time.sleep(random.uniform(1, 3)) 比什么都管用。

第三,验证码是分水岭。简单图形验证码可以用 ddddocr 这类库识别,准确率能到 80% 左右。滑动验证码就麻烦了,得模拟鼠标轨迹,还得处理加密参数。我试过用 Selenium 模拟人工滑动,成功率和滑动速度、加速度曲线直接相关。后来干脆放弃,换了个不需要登录的接口。

动态页面的两条路

一条是 Selenium 或 Playwright,直接驱动浏览器。优点是所见即所得,缺点是慢,开一个 Chrome 实例吃 200MB 内存。抓 100 页数据,半小时起步。

另一条是直接分析 XHR 请求。打开开发者工具 Network 面板,筛选 XHR,刷新页面,找到返回 JSON 的那个请求。复制它的 URL、参数、加密字段,用 requests 直接请求接口。速度快十倍不止。但难点在于,很多接口带签名参数,比如 sign=md5(timestamp + secret),你得逆向 JS 代码找到加密逻辑。

我抓某电商评论时,就卡在签名上。最后用 PyExecJS 直接调用页面里的 JS 函数生成签名,虽然笨,但能跑通。

数据存哪

小规模用 CSV 就够了。pandas.to_csv() 一行搞定。字段里有逗号或换行符,记得加 quoting=csv.QUOTE_ALL。数据量上十万条,换 SQLite 或 MySQL。我一般先用 SQLite 落地,后面要分析再导入 pandas。MongoDB 适合字段不固定的场景,比如不同商品返回的参数数量不一致。

最后说个踩过的坑:某网站返回的 JSON 里,价格字段是 "price": "¥199.00",带货币符号和千分位。直接 float() 会报错。得先 replace("¥", "").replace(",", "")。这种细节,文档里不会写,只能自己撞一次。

    热门排行

    友情链接