python爬虫网站完整代码
凌晨三点,爬虫我盯着终端里滚动的网站完整数据流,第37次修改了那个该死的代码请求头。对方服务器像是爬虫长了眼睛,每次我伪装成浏览器访问,网站完整它都能嗅出爬虫的代码味道,直接甩给我一串403。爬虫直到我加上了Accept-Language和Referer字段,网站完整数据才像泄洪一样涌出来。代码那一刻我意识到,爬虫写爬虫的网站完整根本不是写代码,是代码在跟对方工程师玩心理战。
直接给你看一段能跑的爬虫完整代码吧,爬的网站完整是某公开图书网站的排行榜。别急着复制粘贴,代码先看懂每一行在干什么——这才是重点。
import requests from bs4 import BeautifulSoup import time headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Referer': 'https://www.example.com/' } def fetch_page(url): try: r = requests.get(url, headers=headers, timeout=10) r.raise_for_status() r.encoding = 'utf-8' return r.text except requests.exceptions.RequestException as e: print(f'请求失败: { e}') return None def parse_books(html): soup = BeautifulSoup(html, 'lxml') books = [] for item in soup.select('.book-item'): title = item.select_one('.title').text.strip() price = item.select_one('.price').text.strip() rating = item.select_one('.rating').text.strip() books.append({ 'title': title, 'price': price, 'rating': rating}) return books if __name__ == '__main__': base_url = 'https://www.example.com/books?page={ }' all_books = [] for page in range(1, 6): print(f'正在抓取第{ page}页...') html = fetch_page(base_url.format(page)) if html: page_books = parse_books(html) all_books.extend(page_books) time.sleep(2) # 礼貌性延时,别把人家服务器打爆 else: break print(f'共抓取{ len(all_books)}本书') for book in all_books[:5]: print(book) 这段代码看着简单,坑全在细节里。time.sleep(2)不是随便写的——我试过0.5秒间隔,爬到第3页就被封了IP,换了代理才解封。还有那个lxml解析器,比默认的html.parser快三倍不止,页面结构复杂的时候差距更明显。
说说我踩过的真实教训。第一次写爬虫时,我天真地以为只要带上User-Agent就能伪装成浏览器。结果对方服务器检查了Accept-Encoding,发现我声明支持gzip却不会解压,直接拒绝服务。后来我学会了用response.content配合gzip.decompress处理压缩响应。还有一次,我忘了处理动态加载的内容,用requests拿到的HTML里根本没有我要的数据——那些是JavaScript异步加载的。最后改用Selenium模拟浏览器操作,虽然慢,但确实能拿到渲染后的完整DOM。
如果你要爬的网站有登录功能,事情就变得微妙了。常规做法是用requests.Session()保持会话,先POST提交用户名密码,拿到cookie后再去访问需要认证的页面。但有些网站用了CSRF token,你得先从登录页面提取隐藏字段再一并提交。更狠的还会校验浏览器指纹,WebDriver会被检测出来——这时候就得用undetected-chromedriver这种库来绕过。
写爬虫最忌讳的就是贪。我见过有人一口气开50个线程去抓同一个网站,结果不到一分钟服务器就崩了。对方运维顺着IP摸过来,一封投诉邮件发到学校,整个实验室的IP段都被封了。所以我的原则是:单线程+延时,慢慢爬,一天爬不完就爬两天。数据这东西,晚一天拿到又不会死。
最后说句实在话:爬虫代码本身不值钱,值钱的是你对目标网站的理解。你得花时间研究它的请求规律、反爬机制、数据结构,甚至要读懂对方的JavaScript代码。我花在分析页面上的时间,通常是写代码时间的三倍。别急着写for循环,先打开浏览器开发者工具,看看Network面板里到底发了哪些请求,参数怎么构造的,响应长什么样——搞清楚了这些,代码自然就出来了。
爬虫写多了你会发现,每个网站都是独特的对手。有的用字体反爬,把数字映射成乱码;有的用CSS偏移,文字顺序打乱;还有的干脆在图片上叠加干扰线。但万变不离其宗——只要数据要显示在用户浏览器里,就一定有办法提取。你需要的只是耐心和一点点偏执,就像我凌晨三点还在跟那个403较劲一样。等数据成功落盘的那一刻,你会觉得所有的熬夜都值了。
