Playwright 多语言一体化——Python/Java/.NET 全栈采集实战

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
Elasticsearch Serverless检索通用型,资源抵扣包 100CU*H
简介: 本文以反面教材形式,剖析了在使用 Playwright 爬取懂车帝车友圈问答数据时常见的配置错误(如未设置代理、Cookie 和 User-Agent),并提供了 Python、Java 和 .NET 三种语言的修复代码示例。通过错误示例 → 问题剖析 → 修复过程 → 总结教训的完整流程,帮助读者掌握如何正确配置爬虫代理及其它必要参数,避免 IP 封禁和反爬检测,实现高效数据采集与分析。

爬虫代理

在现代 Web 自动化领域,Playwright 通过其多语言支持可在 Python、Java 及 .NET 三大生态中共享同一底层实现,简化了跨团队协作与维护成本 。然而,若忽略代理IP等必要配置,很容易导致功能异常或被目标网站限制,本文将以反面教材的形式,通过错误示例 → 问题剖析 → 修复过程 → 总结教训,完整演示如何使用爬虫代理(示例域名、端口、用户名、密码)并结合其它策略设置,从 https://www.dongchedi.com 上按汽车型号关键词搜索车友圈问答并进行数据存储与分析 。

错误代码案例

1. Python 版(错误示例)

from playwright.sync_api import sync_playwright

def scrape(keyword):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)  # ❌ 未设置代理
        page = browser.new_page()  # ❌ 未设置 Cookie 和 User‑Agent
        page.goto(f"https://www.dongchedi.com/all-posts?search={keyword}")  # ❌ 忽略 await 时序
        content = page.content()
        # … 后续解析逻辑
        browser.close()

2. Java 版(错误示例)

import com.microsoft.playwright.*;

public class DongchediScraper {
   
    public static void main(String[] args) {
   
        try (Playwright pw = Playwright.create()) {
   
            Browser browser = pw.chromium().launch();  // ❌ 未配置 proxy
            Page page = browser.newPage();             // ❌ 未设置 headers
            page.navigate("https://www.dongchedi.com/all-posts?search=" + args[0]);
            String html = page.content();
            // … 继续处理
            browser.close();
        }
    }
}

3. .NET 版(错误示例)

using Microsoft.Playwright;
using System.Threading.Tasks;

class Program {
   
    public static async Task Main(string[] args) {
   
        using var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();  // ❌ 忽略 proxy
        var page = await browser.NewPageAsync();                 // ❌ 忽略 UA 和 Cookie
        await page.GotoAsync($"https://www.dongchedi.com/all-posts?search={args[0]}");
        var html = await page.ContentAsync();
        // … 继续处理
        await browser.CloseAsync();
    }
}

造成问题

  1. 无代理:目标站点会检测到相同 IP 的频繁请求并封禁,导致请求失败或 429 错误(HTTP Too Many Requests)。
  2. 缺少 Cookie/UA:未模拟真实浏览器环境,常触发反爬检测,返回 CAPTCH A 或重定向登录页面 。
  3. 异步时序错误(Python):漏写 await/使用同步 API 导致页面未完全加载即抓取,数据不完整或抛出超时异常 。

修复过程

1. 核心思路

  • 利用 Playwright 的 context.new_context(Python/JavaScript)或对应参数(Java/.NET)配置代理、Cookie、User‑Agent。
  • 通过 extraHTTPHeadersaddCookies/setExtraHTTPHeaders 方法一次性注入 UA 和 Cookie,确保会话有效。

2. Python 修复代码

from playwright.sync_api import sync_playwright

def scrape(keyword):
    with sync_playwright() as p:
        # 创建带代理与 headers 的浏览上下文
        # 参考亿牛云爬虫代理设置 www.16yun.cn
        context = p.chromium.launch().new_context(
            proxy={
   
                "server": "proxy.16yun.cn:12345",  # 代理域名与端口
                "username": "16YUN",        # 代理用户名
                "password": "16IP"         # 代理密码
            },
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "\
                       "(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",  # 自定义 UA
            extra_http_headers={
   
                "Cookie": "sessionid=abcdef12345; locale=zh-CN"  # 示例 Cookie
            }
        )
        page = context.new_page()  # 创建页面
        page.goto(f"https://www.dongchedi.com/all-posts?search={keyword}")  # 正确时序
        # 数据提取示例
        posts = page.query_selector_all(".post-card")
        for post in posts:
            title = post.query_selector("h3").inner_text()
            answer = post.query_selector(".answer").inner_text()
            print(title, answer)
        context.close()

3. Java 修复代码

import com.microsoft.playwright.*;

public class DongchediScraper {
   
  public static void main(String[] args) {
   
    try (Playwright pw = Playwright.create()) {
   
      Browser browser = pw.chromium().launch();
      //参考亿牛云爬虫代理设置 www.16yun.cn
      BrowserContext context = browser.newContext(new Browser.NewContextOptions()
        .setProxy(new Proxy("proxy.16yun.cn:12345", "16YUN", "16IP"))
        .setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "\
                      "(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36")
        .setExtraHTTPHeaders(Map.of("Cookie", "sessionid=abcdef12345; locale=zh-CN"))
      );
      Page page = context.newPage();
      page.navigate("https://www.dongchedi.com/all-posts?search=" + args[0]);
      List<ElementHandle> posts = page.querySelectorAll(".post-card");
      for (ElementHandle post : posts) {
   
        System.out.println(post.querySelector("h3").innerText() + " -> " +
                           post.querySelector(".answer").innerText());
      }
      context.close();
      browser.close();
    }
  }
}

4. .NET 修复代码

using Microsoft.Playwright;
using System;
using System.Threading.Tasks;

class Program {
   
  public static async Task Main(string[] args) {
   
    using var playwright = await Playwright.CreateAsync();
    var browser = await playwright.Chromium.LaunchAsync();
    //参考亿牛云爬虫代理设置 www.16yun.cn
    var context = await browser.NewContextAsync(new BrowserNewContextOptions {
   
      Proxy = new Proxy {
    Server = "proxy.16yun.cn:12345", Username = "16YUN", Password = "16IP" },
      UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "\
                  "(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
      ExtraHTTPHeaders = new Dictionary<string, string> {
   
        ["Cookie"] = "sessionid=abcdef12345; locale=zh-CN"
      }
    });
    var page = await context.NewPageAsync();
    await page.GotoAsync($"https://www.dongchedi.com/all-posts?search={args[0]}");
    var posts = await page.QuerySelectorAllAsync(".post-card");
    foreach (var post in posts) {
   
      var title = await post.QuerySelectorAsync("h3");
      var answer = await post.QuerySelectorAsync(".answer");
      Console.WriteLine(await title.InnerTextAsync() + " -> " + await answer.InnerTextAsync());
    }
    await context.CloseAsync();
    await browser.CloseAsync();
  }
}

总结教训

  • 始终配置代理:避免单机 IP 被限制,尤其是高频采集场景;推荐使用动态切换或域名访问模式以提高稳定性 。
  • 提前注入 Cookie/UA:真实化请求头,绕过简易反爬策略。
  • 遵循异步时序:Playwright 同步与异步 API 各有适用场景,务必正确使用 Await/Sync 模式,避免未加载完全就开始爬取。
  • 多语言示例统一化:同一底层 API 实现,减少团队维护成本,代码示例可互相参考。

通过上述反面教材式拆解,读者可以快速掌握 Playwright 在多语言环境下的配置要点,实战抓取懂车帝车友圈问答数据并完成存储与分析。

相关文章
|
9天前
|
Java API 微服务
2025 年 Java 核心技术全面升级与实战应用详解
这份Java校招实操内容结合了最新技术趋势,涵盖核心技术、微服务架构、响应式编程、DevOps及前沿技术等六大模块。从函数式编程到Spring Cloud微服务,再到容器化与Kubernetes部署,帮助你掌握企业级开发技能。同时,提供AI集成、区块链实践和面试技巧,包括高频算法题与系统设计案例。通过学习这些内容,可应对90%以上的Java校招技术面试,并快速上手实际项目开发。资源链接:[点此获取](https://pan.quark.cn/s/14fcf913bae6)。
89 41
|
11天前
|
存储 Java 数据安全/隐私保护
Java技术栈揭秘:Base64加密和解密文件的实战案例
以上就是我们今天关于Java实现Base64编码和解码的实战案例介绍。希望能对你有所帮助。还有更多知识等待你去探索和学习,让我们一同努力,继续前行!
66 5
|
11天前
|
缓存 NoSQL Java
校招 Java 面试常见知识点及实战案例全解析
本文全面解析了Java校招面试中的常见知识点,涵盖Java新特性(如Lambda表达式、、Optional类)、集合框架高级应用(线程安全集合、Map性能优化)、多线程与并发编程(线程池配置)、JVM性能调优(内存溢出排查、垃圾回收器选择)、Spring与微服务实战(Spring Boot自动配置)、数据库与ORM框架(MyBatis高级用法、索引优化)、分布式系统(分布式事务、缓存应用)、性能优化(接口优化、高并发限流)、单元测试与代码质量(JUnit 5、Mockito、JaCoCo)以及项目实战案例(电商秒杀系统、社交消息推送)。资源地址: [https://pan.quark.cn/s
57 4
|
27天前
|
存储 安全 Java
【高薪程序员必看】万字长文拆解Java并发编程!(4-1):悲观锁底层原理与性能优化实战
目录4. JVM字节码文件4.1. 字节码文件-组成4.1.1. 组成-基础信息4.1.1.1. 基础信息-魔数4.1.1.2. 基础信息-主副版本号4.1.2. 组成-常量池4.1.3. 组成-方法4.1.3.1. 方法-工作流程4.1.4. 组成-字段4.1.5. 组成-属性4.2. 字节码文件-查看工具4.2.1. javap4.2.2. jclasslib4.2.3. 阿里Arthas
34 0
|
27天前
|
安全 Java 程序员
【高薪程序员必看】万字长文拆解Java并发编程!(6-2):从CAS无锁机制到Atomic原子类实战指南
🌟 ​🌟今天给大家带来的是 ​💻⚡在这篇文章中,我们将一起探索:🔹 ​的底层原理,它是如何通过 ​实现无锁并发的?🔹 ​的终极对决,为什么高并发场景下CAS性能更优?🔹 ​的陷阱与解决方案——和实战演示!🔹 ​​(LongAdder等)的使用场景与性能对比🔹 危险的 ​黑魔法:为什么阿里禁止使用却又是并发库的基石?无论你是:✅ ​​(BATJ高频考点)✅ ​​(如何设计百万级计数器)✅ ​​(从Java代码到CPU指令的全链路分析)这篇文章都会让你收获满满!✨。
33 0
|
27天前
|
安全 Java 程序员
【高薪程序员必看】万字长文拆解Java并发编程!(6-1):从CAS无锁机制到Atomic原子类实战指南
🌟 ​🌟今天给大家带来的是 ​💻⚡在这篇文章中,我们将一起探索:🔹 ​的底层原理,它是如何通过 ​实现无锁并发的?🔹 ​的终极对决,为什么高并发场景下CAS性能更优?🔹 ​的陷阱与解决方案——和实战演示!🔹 ​​(LongAdder等)的使用场景与性能对比🔹 危险的 ​黑魔法:为什么阿里禁止使用却又是并发库的基石?无论你是:✅ ​​(BATJ高频考点)✅ ​​(如何设计百万级计数器)✅ ​​(从Java代码到CPU指令的全链路分析)这篇文章都会让你收获满满!✨。
34 0
|
Python
PYTHON实战两数之和
1. 两数之和 难度:简单 收藏 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。
232 0
PYTHON实战两数之和
|
3月前
|
机器学习/深度学习 存储 设计模式
Python 高级编程与实战:深入理解性能优化与调试技巧
本文深入探讨了Python的性能优化与调试技巧,涵盖profiling、caching、Cython等优化工具,以及pdb、logging、assert等调试方法。通过实战项目,如优化斐波那契数列计算和调试Web应用,帮助读者掌握这些技术,提升编程效率。附有进一步学习资源,助力读者深入学习。
|
1月前
|
数据采集 安全 BI
用Python编程基础提升工作效率
一、文件处理整明白了,少加两小时班 (敲暖气管子)领导让整理100个Excel表?手都干抽筋儿了?Python就跟铲雪车似的,哗哗给你整利索!
64 11
|
3月前
|
人工智能 Java 数据安全/隐私保护
[oeasy]python081_ai编程最佳实践_ai辅助编程_提出要求_解决问题
本文介绍了如何利用AI辅助编程解决实际问题,以猫屎咖啡的购买为例,逐步实现将购买斤数换算成人民币金额的功能。文章强调了与AI协作时的三个要点:1) 去除无关信息,聚焦目标;2) 将复杂任务拆解为小步骤,逐步完成;3) 巩固已有成果后再推进。最终代码实现了输入验证、单位转换和价格计算,并保留两位小数。总结指出,在AI时代,人类负责明确目标、拆分任务和确认结果,AI则负责生成代码、解释含义和提供优化建议,编程不会被取代,而是会更广泛地融入各领域。
116 28

推荐镜像

更多