受欢迎的博客标签

爬虫采集技术(一)无头浏览器headless爬取网页技术方案选型

Published

还是用 headless 浏览器操作 Selenium 过时了,Playwright 是微软的,google 的是 Puppeteer,包装 Chromium 等浏览器给测试等场景用。

一、爬虫基本知识

网站的网页数据有两种呈现方式。

一种是同步加载的。另一种是异步加载的,也即我们常说的用ajax。

如果是同步加载的没有JavaScripts加载数据需求,单独用AngleSharp直接解析网页就可以搞定.

如果是异步加载的有JavaScripts加载数据需求的,就需要上真正的无头浏览器组件才能搞定。

在与反爬虫的对抗中,我们爬虫的大招有两个:

一)多种ip跟换方式(例如adsl|代理|tor等)。

(二)无头浏览器,使用自动化的技术来进行自动数据抓取,模拟鼠标与键盘事件,可以用于破解验证码,js解析,诡异的模糊数据这类型的反爬虫技术。

(三)浏览器插件

使用的是beautifulsoup+requests 直接对ajax的api爬数据就好了,你所说的爬的url,只是从用户角度来模拟的 上面几位提到的直接查看发起的请求,然后分析请求的规律,猜出请求的接口是如何设计的,这样的话,比爬取HTML页面更快,但是有一个问题,就是有可能人家接口的调用方式你不一定能完全猜测出来,为了更高的成功率(对于我的业务来讲,速度不是最主要的,虽然他也很重要),我使用过两种方式,可以爬取几乎任何网站任何形式的内容。

Chrome 浏览器用来成为我整个爬取的底层技术,我的插件则用来控制浏览器,服务器端发起一次爬取请求,插件收到之后,使用Chrome打开网页,然后直接抓取网页上面的验证码图片,如果我判断出网站是要求手机验证的,那么就直接点击一下发送验证码(插件直接发起一次点击事情),这个时候,服务器端则通知用户端输入(若是图片验证码,客户端也会直接显示出来),然后提交,插件将用户提交的数据填写到打开的网页中,点击提交。 因为网页就是浏览器打开的,所以,爬取任何数据都不是问题了。

(四)Remote Browser

Remote Browser 基于 Web Extensions API 标准构建,是一个使用 JavaScript 以编程方式控制诸如 Chrome 和 Firefox 之类的网络浏览器的库。此前你可能已经听说过类似的浏览器自动化框架,例如 Puppeteer 和 Selenium。

Remote Browser 与这些框架非常相似,它可用于完成与 UI 测试、服务器端渲染(SSR)以及网页抓取相关的各种任务。但不同之处在于它使用标准的跨浏览器兼容技术构建,其主要目标是促进与现有 API 的交互,而不是创建自己新的 API。

下面这段示例代码的作用是导航至选项卡并使用 Remote Browser 进行截图

import Browser from 'remote-browser';
(async () => {
  // Create and launch a new browser instance.
  const browser = new Browser();
  await browser.launch();
  // Directly access the Web Extensions API from a remote client.
  const tab = await browser.tabs.create({ url: 'https://intoli.com' });
  const screenshot = await browser.tabs.captureVisibleTab();
})();
var options = new ConnectOptions()
{
    BrowserWSEndpoint = $"wss://www.externalbrowser.io?token={apikey}"
};
const browser = await puppeteer.connect({ browserWSEndpoint: 'wss://chrome.browserless.io/' });

(五)编程直接控制浏览器

获取当前谷歌安装位置

调用谷歌命令,将html直接打印成pdf并保存成文件方法

c#

https://www.debugger.wiki/article/html/1628426160308886

二、无头浏览器(无界面的浏览器)迭代发展的三个阶段

按出现时间顺序,选最新阶段出现的无头浏览器

第1阶段:PhantomJS 

第2阶段:selenium-webdriver

第3阶段:Puppeteer
PuppeteerSharp :for  .net

第4阶段:Puppeteer
Microsoft.Playwright

A web browser without a graphical user interface, controlled programmatically. Used for automation, testing, and other purposes.

PhantomJS(放弃)

 

早期的无头浏览器王者,但自2017年起已停止维护。其核心引擎(QtWebKit)陈旧,无法适配现代Web标准,已被后续工具完全取代.

在最新版中的 Selenium 中已经不支持 PhantomJS了

 selenium-webdriver

它通过驱动各浏览器的原生驱动(如ChromeDriver、geckodriver)来控制真实浏览器。用来模拟浏览器操作(selenium + webdriver)来写爬虫。

浏览器自动化的“老大哥”,支持多语言,速度慢、操作繁琐

Puppeteer

 

由Google Chrome团队开发,通过DevTools协议直接控制Chromium/Chrome。

Chrome 团队连续放了两个大招 Headless Chrome 和对应的 NodeJS API Puppeteer,直接让 PhantomJS 和 Selenium IDE for Firefox 作者宣布没必要继续维护其产品.

作为selenium+webdriver的优秀替代,ppeteer就是一个很好的选择。

谷歌出品,专注于 Chromium 浏览器,速度快但默认只支持 Chrome/Chromium。

Puppeteer

Puppeteer 是一个通过 DevTools Protocol 控制 headless chrome 的 high-level Node 库,也可以通过设置使用 非 headless Chrome.我们手工可以在浏览器上做的事情 Puppeteer 都能胜任:

生成网页截图或者 PDF
爬取大量异步渲染内容的网页,基本就是人肉爬虫
模拟键盘输入、表单自动提交、UI 自动化测试

github:https://github.com/puppeteer/puppeteer

PuppeteerSharp

Puppeteer Sharp是官方Node.JS Puppeteer API的.NET 移植。

作者博客: http://www.hardkoded.com/

 项目地址:https://github.com/hardkoded/puppeteer-sharp

Headless Chrome设置教程,chrome无头浏览器(无界面的浏览器),彻底告别phantomjs

chrome发布了Headless Chrome,就是可以实现和phantomjs一样无头浏览器,以后使用selenium chromewebdriver不需要再弹出浏览器。 我也一直在跟踪这个功能,Google花了好长时间找方法才设置成功,现在分享给国内,其实设置很简单(我用的是Python3.6版本):

1:将chrome升级到最新的60版本,只有这个版本或者更新的版本才支持Headless

2:在代码行里设置chrome,加上这行代码即可options.add_argument("--headless") 或者options.add_argument("headless") ,暂时还没看出两者区别。  .

 

A list of (almost) all headless web browsers in existence

https://www.cnblogs.com/VAllen/p/PuppeteerSharp-AngleSharp-CrawlerSamples.html

 

Playwright for .NET

由微软官方团队积极维护。

原生支持所有现代渲染引擎:Chromium、Firefox、WebKit。

天生跨浏览器,速度比 Selenium 快,API 设计更现代、好用,已经成了很多自动化和爬虫项目的首选

 

CloakBrowser

github:https://github.com/CloakHQ/CloakBrowser

CloakBrowser 完全不在这个层面玩。它 fork 了 Chromium 源码,直接在 C++ 层面修改了 49 个位置的代码,重新编译出一个定制的 Chromium 二进制文件。补丁覆盖的范围:

 

每次启动都会从一个种子生成一套全新的、内部一致的指纹身份——GPU 型号、硬件参数、屏幕尺寸、Canvas/WebGL/Audio 噪声、字体列表全部联动。不是随机拼凑,而是像一个真实的设备配置。

blog:https://www.cnblogs.com/itech/p/20077581

 

三、反爬虫技术

 

 

 

网站现在反爬虫检测技术:

验证码(CAPTCHA)

行为模式
浏览器指纹 - User-Agent 检查
会话行为
是否人类交互
不是只看“时间间隔”

限流与 IP 封禁

 

1.爬虫被识别的原因

1.1 特征码的问题

1.1.1 phantomjs (放弃)

phantomjs 会被好些网站自动认作爬虫。因为正常人是不会用这个浏览器的。

1.2.1 selenium(puppeteer也会被识别)

1.2.1 通过辨认一些带有selenium特征的javascript预定义变量来实现的

因为浏览器中的window.navigator.webdriver属性被JS暴露了出来,而被服务器端所识别,触发了服务器的反爬策略,导致爬取失败。

Chrome从v63版本开始添加了这一属性,那么我们就可以使用低于v63版本的Chrome来实现即可(v62.0.3202.62版本测试通过,当然也不要忘了将chromedriver换成对应的版本)

这种识别是通过辨认一些带有selenium特征的javascript预定义变量来实现的,且不同的浏览器所能暴露出来的特征不一样。

例如:"window.navigator.webdriver",在非selenium环境下其值为undefined,而在selenium环境下,其值为true。

解决方法1:用的chrome,解决方法是改掉这些变量的名称。

自己下chromedriver的源码,把里面特征变量的名字改掉,然后重新编译,结果似乎是骗过了目标网站。

注意:在此之前你最好不要被网站加入黑名单里,因为你的浏览器有自己独特的指纹可以被追踪。

解决方法2:手动打开浏览器,然后用selenium控制这个浏览器跑程序。

selenium打开浏览器,自己手动操作一样不行。解决方法就是手动打开浏览器,然后用selenium控制这个浏览器跑程序。

 

总结:用来模拟浏览器操作(selenium + webdriver)来写爬虫。但是稍微有点反爬的网站都会对selenium和webdriver进行识别,被爬网站只需要在前端js添加一下判断脚本,很容易就可以判断出是真人访问还是webdriver。虽然也可以通过中间代理的方式进行js注入屏蔽webdriver检测,但是webdriver对浏览器的模拟操作(输入、点击等等)都会留下webdriver的标记,同样会被识别出来,要绕过这种检测,只有重新编译webdriver,麻烦自不必说,难度不是一般大。

 

1.2 通过多种技术来实现对机器人的识别

 

 

爬虫要用一些调度策略,避免触发机器人识别程序。机器人识别程序有些很简单,比如,根据单位时间内访问的网页数量,有些比较复杂,比如根据访问的网页间关系,还有更复杂的根据监听网页上的事件。

 

解决办法:

Headers should be similar to common browsers, including :
User-Agent : use a recent one (see https://developers.whatismybrowser.com/useragents/explore/), or better, use a random recent one if you make multiple requests (see https://github.com/skratchdot/random-useragent)
Accept-Language : something like "en,en-US;q=0,5" (adapt for your language)
Accept: a standard one would be like "text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8"
If you make multiple request, put a random timeout between them
If you open links found in a page, set the Referer header accordingly
Images should be enabled
Javascript should be enabled
Check that "navigator.plugins" and "navigator.language" are set in the client javascript page context
Use proxies

 

传统方案(playwright-stealth、puppeteer-extra-plugin-stealth)的工作方式是在页面加载前注入一段 JS,覆盖 navigator.webdriver、修改 chrome 对象、伪造 Canvas 指纹。问题是:

网站可以在 JS 注入之前就读取指纹
注入的 JS 本身可以被检测到
Chrome 一更新,补丁就失效

四、 undetected chromedrive 技术

1.通过 Chloudflare 反爬虫检测源项目undetected-chromedriver(py)

此项目在近期的 1.5.0 更新中解决了 Cloudflare 的爬虫检测问题。

https://blog.csdn.net/weixin_41951954/article/details/124730933

https://github.com/ultrafunkamsterdam/undetected-chromedriver

2.cloudflare scrape

A simple PHP module to bypass Cloudflare's anti-bot page 

https://github.com/Anorov/cloudflare-scrape

为了绕过这个 CloudFlare 开发的 Python 库 cloudflare-scrape

用上它就可以无感爬取使用了 CloudFlare 的网站。

https://cloud.tencent.com/developer/article/1512177

 

playwright+ocr

 

传统方案(playwright-stealth、puppeteer-extra-plugin-stealth)的工作方式是在页面加载前注入一段 JS,覆盖 navigator.webdriver、修改 chrome 对象、伪造 Canvas 指纹。问题是:

网站可以在 JS 注入之前就读取指纹
注入的 JS 本身可以被检测到
Chrome 一更新,补丁就失效

 

CloakBrowser

CloakBrowser 完全不在这个层面玩。它 fork 了 Chromium 源码,直接在 C++ 层面修改了 49 个位置的代码,重新编译出一个定制的 Chromium 二进制文件

CloakBrowser 49 个 C++ 源码级补丁,不是在 JS 层面打补丁,而是从根本上消除了 Chromium 的自动化痕迹。reCAPTCHA v3 拿 0.9,Cloudflare Turnstile 直接过,TLS 指纹和正常 Chrome 一模一样。

类别补丁内容
Canvas/WebGL/Audio在渲染层注入噪声,指纹每次不同但内部一致
GPU 信息vendor/renderer 字符串替换为真实硬件值
硬件参数屏幕分辨率、CPU 核心数、内存大小全部伪装
Navigatorwebdriver=falseplugins.length=5chrome 对象完整存在
UA 字符串去掉 HeadlessChrome 标识,返回正常 Chrome/146.0.0.0
WebRTCICE 候选和 IP 地址自动匹配代理出口
TLS 指纹ja3/ja4/Akamai 指纹与正常 Chrome 完全一致
CDP 行为键盘、鼠标、滚轮操作全部人类化
网络时序DNS/连接/SSL 时间归零,Proxy-Connection 头剥离

Camoufox 也是 C++ 源码级补丁,但它基于 Firefox,而 CloakBrowser 基于 Chromium。对大多数 Playwright/Puppeteer 用户来说,Chromium 生态的兼容性好得多。

 

CloakBrowser for .NET

https://github.com/CloakHQ/CloakBrowser/blob/main/dotnet/README.md

 

五、反爬虫检测方案对比

特性Playwrightplaywright-stealthundetected-chromedriverCamoufoxCloakBrowser
reCAPTCHA v30.10.3-0.50.3-0.70.7-0.90.9
Cloudflare Turnstile失败偶尔偶尔通过通过
补丁级别JS 注入配置补丁C++(Firefox)C++(Chromium)
Chrome 更新后存活经常失效经常失效
维护状态活跃停滞停滞不稳定活跃

 

 

Useful links

反爬虫中 chrome 无头浏览器的几种检测与绕过方式 chrome 无头浏览器的几种检测方式
前端如何检测 Chrome-Headless 不被爬虫虐
爬虫如何隐藏 Headles-Chrome 不被检测出来

Detecting Headles Chrome(MAKING CHROME HEADLESS UNDETECTABLE)

Can a website detect when you are using Selenium with chromedriver?

IT IS *NOT* POSSIBLE TO DETECT AND BLOCK CHROME HEADLESS

MAKING CHROME HEADLESS UNDETECTABLE

 

Nginx反爬虫: 禁止某些User Agent抓取网站