资讯动态

Playwright实战:从零到一,轻松爬取豆瓣电影TOP10并生成Excel报表

发布时间:2026/9/10 12:34:52 来源:尧图企业网站定制
1. 为什么选择Playwright爬取豆瓣电影最近几年网页自动化工具层出不穷从早期的Selenium到现在的Playwright技术迭代速度非常快。作为一个长期从事数据采集的开发者我实测过市面上几乎所有主流工具最终发现Playwright在易用性和稳定性上表现尤为突出。特别是对于刚入门的新手来说它提供的同步API和自动生成代码功能能让你快速上手而不会被复杂的配置劝退。Playwright最大的优势在于它原生支持Chromium、Firefox和WebKit三大浏览器引擎这意味着你写的脚本几乎能在所有现代浏览器上运行。还记得我第一次用Selenium时光是解决浏览器驱动兼容性问题就折腾了大半天。而Playwright通过内置驱动彻底解决了这个痛点安装完就能直接用这对新手来说简直太友好了。另一个让我选择Playwright的原因是它的执行速度。在爬取豆瓣电影这类动态渲染的页面时传统的requestsBeautifulSoup组合经常拿不到完整数据。Playwright则能完美模拟真实用户操作等页面完全加载后再提取数据。我做过对比测试在相同网络环境下Playwright获取完整DOM树的速度比Selenium快30%左右。2. 环境准备与基础配置2.1 安装Playwright安装Playwright只需要两条命令但有些细节需要注意。首先建议升级pip到最新版本这能避免很多依赖冲突问题pip install --upgrade pip pip install playwright安装完Python包后还需要安装浏览器二进制文件。这里有个小技巧如果你在国内可能会遇到下载速度慢的问题。可以通过设置环境变量来使用国内镜像源PLAYWRIGHT_DOWNLOAD_HOSThttps://npmmirror.com/mirrors/playwright playwright install安装过程大概需要2-3分钟取决于你的网络速度。完成后可以运行playwright --version检查是否安装成功。我建议同时安装chromium、firefox和webkit三个浏览器虽然本项目只用chromium但多浏览器支持是Playwright的特色功能playwright install chromium firefox webkit2.2 初始化项目结构创建一个干净的目录来存放项目文件是个好习惯。我的典型项目结构是这样的douban_movie_crawler/ ├── main.py # 主程序 ├── utils.py # 工具函数 ├── config.py # 配置文件 └── output/ # 输出目录在main.py中我们先导入必要的模块。除了playwright自带的sync_api我们还会用到xlwt来处理Excel文件import xlwt from playwright.sync_api import sync_playwright3. 爬取豆瓣电影TOP10实战3.1 启动浏览器并访问页面使用Playwright的第一步是创建浏览器实例。这里有个重要参数headless默认是True无头模式。对于调试阶段我强烈建议设置为False这样你能看到实际浏览器窗口方便观察脚本执行情况def run(playwright): browser playwright.chromium.launch( headlessFalse, slow_mo1000 # 放慢操作速度方便观察 )创建context对象相当于打开一个隐私浏览窗口不同context之间完全隔离。这在需要多账号登录的场景特别有用context browser.new_context( user_agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 )访问豆瓣电影首页时建议增加超时设置。我遇到过因为网络波动导致页面加载失败的情况合理的超时设置能提高脚本稳定性page context.new_page() page.goto(https://movie.douban.com/, timeout60000)3.2 定位和提取数据豆瓣电影TOP10榜单实际上是通过AJAX动态加载的直接访问首页可能看不到。我们需要先点击排行榜链接page.click(text排行榜) page.wait_for_selector(.billboard-bd) # 等待榜单加载提取数据时CSS选择器和XPath是最常用的两种方式。我更喜欢CSS选择器因为它的语法更简洁items page.query_selector_all(#billboard div.billboard-bd table tbody tr)不过有时候XPath更灵活特别是处理没有明确class或id的元素时items page.query_selector_all(//*[idbillboard]/div[2]/table/tbody/tr)提取到的每个tr元素包含电影名称和链接我们需要进一步解析movie_list [] for item in items: name item.query_selector(td:nth-child(1) a).text_content() link item.query_selector(td:nth-child(1) a).get_attribute(href) rating item.query_selector(td:nth-child(2)).text_content() movie_list.append((name, link, rating))4. 数据存储与Excel导出4.1 准备Excel文件使用xlwt创建Excel文件时编码设置很重要。豆瓣电影可能包含中文和其他特殊字符utf-8编码能确保不会出现乱码workbook xlwt.Workbook(encodingutf-8) worksheet workbook.add_sheet(豆瓣电影TOP10)设置样式可以让表格更美观。我通常会定义几种常用样式style_header xlwt.easyxf( font: bold on; align: vert centre, horiz center ) style_normal xlwt.easyxf(align: vert centre)4.2 写入数据表头应该清晰表明每列的内容。除了电影名称和链接我还增加了评分列worksheet.write(0, 0, 豆瓣电影TOP10, style_header) worksheet.write(2, 0, 排名, style_header) worksheet.write(2, 1, 电影名称, style_header) worksheet.write(2, 2, 评分, style_header) worksheet.write(2, 3, 详情链接, style_header)写入数据时要注意行号控制。我习惯从第3行开始写实际数据0-based索引for idx, (name, link, rating) in enumerate(movie_list): row idx 3 worksheet.write(row, 0, idx1, style_normal) worksheet.write(row, 1, name, style_normal) worksheet.write(row, 2, rating, style_normal) worksheet.write(row, 3, link, style_normal)4.3 调整格式并保存合适的列宽能让Excel更易读。我通常根据内容长度动态设置worksheet.col(0).width 2000 # 排名列 worksheet.col(1).width 6000 # 名称列 worksheet.col(2).width 3000 # 评分列 worksheet.col(3).width 12000 # 链接列最后保存文件时建议使用绝对路径并处理可能出现的异常try: workbook.save(output/douban_top10.xls) except Exception as e: print(f保存文件失败: {e})5. 完整代码与优化建议5.1 完整脚本将前面的代码片段整合起来完整的脚本如下import xlwt from playwright.sync_api import sync_playwright def get_movie_data(page): page.click(text排行榜) page.wait_for_selector(.billboard-bd) items page.query_selector_all(#billboard div.billboard-bd table tbody tr) movie_list [] for item in items: name item.query_selector(td:nth-child(1) a).text_content() link item.query_selector(td:nth-child(1) a).get_attribute(href) rating item.query_selector(td:nth-child(2)).text_content() movie_list.append((name, link, rating)) return movie_list def save_to_excel(data, filename): workbook xlwt.Workbook(encodingutf-8) worksheet workbook.add_sheet(豆瓣电影TOP10) # 设置样式 style_header xlwt.easyxf(font: bold on; align: vert centre, horiz center) style_normal xlwt.easyxf(align: vert centre) # 写入表头 worksheet.write(0, 0, 豆瓣电影TOP10, style_header) worksheet.write(2, 0, 排名, style_header) worksheet.write(2, 1, 电影名称, style_header) worksheet.write(2, 2, 评分, style_header) worksheet.write(2, 3, 详情链接, style_header) # 写入数据 for idx, (name, link, rating) in enumerate(data): row idx 3 worksheet.write(row, 0, idx1, style_normal) worksheet.write(row, 1, name, style_normal) worksheet.write(row, 2, rating, style_normal) worksheet.write(row, 3, link, style_normal) # 调整列宽 worksheet.col(0).width 2000 worksheet.col(1).width 6000 worksheet.col(2).width 3000 worksheet.col(3).width 12000 workbook.save(filename) def main(): with sync_playwright() as playwright: browser playwright.chromium.launch(headlessFalse) context browser.new_context() page context.new_page() page.goto(https://movie.douban.com/) movie_data get_movie_data(page) page.close() context.close() browser.close() save_to_excel(movie_data, output/douban_top10.xls) if __name__ __main__: main()5.2 常见问题排查在实际运行中可能会遇到几个典型问题元素定位失败豆瓣前端偶尔会改版导致选择器失效。这时候可以使用Playwright的page.pause()方法进入调试模式尝试更宽松的选择器比如text排行榜改为a:has-text(排行榜)反爬机制如果频繁访问可能会触发验证码。解决方案包括增加slow_mo参数放慢操作速度设置随机延迟page.wait_for_timeout(random.randint(1000,3000))数据缺失确保等待足够长时间让数据加载page.wait_for_selector(.billboard-bd, stateattached, timeout10000)5.3 扩展思路这个基础项目可以进一步扩展添加异常处理使脚本更健壮使用pandas替代xlwt支持更复杂的Excel操作爬取更多信息如导演、主演、短评等设置定时任务每天自动更新榜单第一次运行这个脚本时我因为没加足够的等待时间导致数据获取不全。后来发现Playwright的wait_for_selector比固定sleep可靠得多。建议新手在写自动化脚本时一定要充分考虑网络延迟和页面加载时间的影响

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价