用Python的网站requests库加BeautifulSoup,20行代码就能把一个静态网页的数据标题全抓下来。这是教程我三年前第一次成功爬数据的场景,目标是网站一个本地书店的促销页面。代码跑通那一刻挺兴奋,数据但很快发现事情没那么简单——网页里一半内容是教程JavaScript动态加载的,requests拿到的网站HTML里根本没有。
所以爬虫的数据第一件事不是写代码,是教程判断目标页面属于哪种类型。右键查看网页源代码,网站如果你要的数据数据在源代码里能找到,那就是教程静态页面,requests + BeautifulSoup够用。网站如果源代码里搜不到、数据但浏览器页面上能看到,教程说明数据是JS渲染出来的,得换工具。selenium能模拟浏览器行为,慢但省心;playwright更快更现代,我现在的首选。还有一种情况是数据通过XHR接口异步加载,打开开发者工具的Network面板,筛选XHR/Fetch请求,往往能直接找到返回JSON的API地址,直接请求接口比解析HTML高效得多。
请求头不是可选项
很多人第一次爬数据失败,是因为没加User-Agent。Python的requests默认UA是
python-requests/2.x,服务器一眼就能识别出这不是浏览器。加上一个正常的浏览器UA,成功率立刻不同:headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } resp = requests.get(url, headers=headers)更严格的网站还会检查Referer、Cookie甚至TLS指纹。我遇到过一个电商站,同样的URL和UA,curl能拿到数据,Python requests返回403。后来用curl_cffi这个库模拟了浏览器的TLS指纹才通过。这种反爬级别不算常见,但说明一个事实:请求头只是最基础的伪装。
解析HTML时别用正则
我见过有人用正则表达式从HTML里提取数据,短期能用,页面结构一改就全废。BeautifulSoup的
select()方法支持CSS选择器,定位精准且容错性好。比如抓取所有文章标题:soup = BeautifulSoup(resp.text, "html.parser") titles = soup.select("h2.article-title") for t in titles: print(t.get_text(strip=True))lxml解析器比html.parser快不少,装上
lxml后把解析器换掉就行。如果目标是结构极其规整的页面,XPath配合lxml的etree也很顺手,但CSS选择器对我来说更直观。控制频率是基本礼貌
我早期写过一个脚本,循环里没加任何延时,对着一个论坛连发了三百多个请求。结果IP被封了24小时。后来养成习惯,每次请求之间
time.sleep(1)到time.sleep(3)随机停顿。对于大规模抓取,用asyncio+aiohttp做并发控制,配合信号量限制同时请求数,比无脑多线程稳得多。robots.txt值得看一眼。它不是法律文件,但表达了网站运营者的意愿。有些站明确禁止爬取特定路径,无视它可能带来麻烦。我个人的原则是:公开数据、低频抓取、不增加服务器负担,这三条守住,大多数场景不会出问题。
数据存哪里
小规模直接存CSV,pandas的
to_csv()一行搞定。需要去重和查询就用SQLite,Python标准库自带sqlite3,零配置。数据量上了百万级再考虑MongoDB或PostgreSQL。我一般先用CSV验证数据质量,确认字段没问题再入库,避免反复改表结构。爬虫写多了会发现,技术难度往往不在代码本身,而在目标网站的反爬策略和数据结构的混乱程度上。同一个网站今天能爬、明天改版了就得重写解析逻辑。所以写的时候尽量把请求逻辑和解析逻辑分开,页面结构变了只改解析部分,省事。
顶: 15踩: 8






评论专区