数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶、逆向相关文章,为实现从易到难全方位覆盖,特设【0基础学爬虫】专栏,帮助小白快速入门爬虫,本期为自动化工具 playwright 的使用。
上期文章中讲到了自动化工具 Selenium 的基本使用方法,也介绍了 Selenium 的优缺点。Selenium的功能非常强大,支持所有现代浏览器。但是 Selenium 使用起来十分不方便,我们需要提前安装好浏览器,然后下载对应版本的驱动文件,当浏览器更新后驱动文件也得随之更新。如果想要大规模且长期的采集数据,那么部署 Selenium 时环境配置会是一个大问题。因此本期我们将介绍一款更加好用的自动化工具 Playwright 。
Playwright是一个用于自动化Web浏览器测试和Web数据抓取的开源库。它由Microsoft开发,支持Chrome、Firefox、Safari、Edge和WebKit浏览器。Playwright的一个主要特点是它能够在所有主要的操作系统(包括Windows、Linux和macOS)上运行,并且它提供了一些强大的功能,如跨浏览器测试、支持无头浏览器、并行执行测试、元素截图和模拟输入等。它主要有以下优势:
使用 Playwright 需要 Python版本在3.7以上。
安装 Playwright 可以直接使用 pip 工具:
pip install playwright
安装完成后需要进行初始化操作,安装所需的浏览器。
playwright install
执行上述指令时,Playwright 会自动安装多个浏览器(Chromium、Firefox 和 WebKit)并配置驱动,所以速度较慢。
Playwright 支持同步与异步两种模式,这里分开来进行讲解。
使用 Playwright 时可以选择启动安装的三种浏览器(Chromium、Firefox 和 WebKit)中的一种。
from playwright.sync_api import sync_playwright
# 调用sync_playwright方法,返回浏览器上下文管理器
with sync_playwright() as p:
# 创建谷歌浏览器示例,playwright默认启动无头模式,设置headless=False,即关闭无头模式
browser=p.chromium.launch(headless=False)
# 新建选项卡
page=browser.new_page()
# 跳转到目标网址
page.goto("http://baidu.com")
# 获取页面截图
page.screenshot(path='example.png')
# 打印页面的标题,也就是title节点中的文本信息
print(page.title())
# 关闭浏览器
browser.close()
# 输出:百度一下,你就知道
可以看到,Playwright 的使用也比较简单,语法比较简洁,而且浏览器的启动速度以及运行速度也很快。
异步代码的编写方法与同步基本一致,区别在于同步调用的是 sync_playwright,异步调用的是 async_playwright。最终运行效果与同步一致。
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser=await p.chromium.launch(headless=False)
page=await browser.new_page()
await page.goto("http://baidu.com")
# 打印网页源代码
print(await page.content())
await browser.close()
asyncio.run(main())
Playwright 提供了代码生成功能,这个功能可以对我们在浏览器上的操作进行录制并生成代码,它可以有效提高程序的编写效率。代码生成功能需要使用 Playwright 命令行中的 codegen实现,codegen 命令存在如下主要参数:
-o :将生成的脚本保存到指定文件
--target :生成的语言,默认为 Python
--save-trace :记录会话的跟踪并将其保存到文件中
-b :要使用的浏览器,默认为 chromium
--timeout :设置页面加载的超时时间
--user-agent :指定UA
--viewport-size :指定浏览器窗口大小
我们在命令行执行命令:playwright codegen -o script.py
执行命令后会弹出一个 chromium 浏览器与脚本窗口,当我们在浏览器上进行操作时,脚本窗口会根据我们的操作生成对应代码。当我们操作结束后,关闭浏览器,在当前目录下会生成一个 script.py 文件,该文件中就是我们在进行浏览器操作时,Playwright 录制的代码。我们运行该文件,就会发现它在复现我们之前的操作。
代码生成功能的实用性其实较为一般,它只能实现比较简单的操作,当遇到复杂操作时,生成的代码就容易出现问题。最好的方式是使用代码生成功能生成部分操作的代码,然后再手动去修改它生成的代码。
上一步中,我们使用代码生成功能生成了一段代码,我们会发现这段代码中使用到了一个 new_context 方法,通过这个方法创建了一个 content ,然后再去进行其它操作。这个 new_content 方法其实是为了创建一个独立的全新上下文环境,它的目的是为了防止多个测试用例并行时各个用例间不受干扰,当一个测试用例异常时不会影响到另一个。
browser=playwright.chromium.launch()
context=browser.new_context()
page=context.new_page()
Playwright 提供了多种定位器来帮助开发中定位元素。
page.get_by_role() :通过显式和隐式可访问性属性进行定位。
page.get_by_text() :通过文本内容定位。
page.get_by_label() :通过关联标签的文本定位表单控件。
page.get_by_placeholder() :按占位符定位输入。
page.get_by_alt_text() :通过替代文本定位元素,通常是图像。
page.get_by_title() :通过标题属性定位元素。
page.get_by_test_id() :根据data-testid属性定位元素(可以配置其他属性)。
page.locator():拓展选择器,可以使用 CSS 选择器进行定位
使用定位器最好的方式就是上文中讲到的利用代码生成功能来生成定位代码,然后手动去修改,这里就不做尝试。
Playwright 支持 CSS、Xpath 和一些拓展选择器,提供了一些比较方便的使用规则。
CSS 选择器
# 匹配 button 标签
page.locator('button').click()
# 根据 id 匹配,匹配 id 为 container 的节点
page.locator('#container').click()
# CSS伪类匹配,匹配可见的 button 按钮
page.locator("button:visible").click()
# :has-text 匹配任意内部包含指定文本的节点
page.locator(':has-text("Playwright")').click()
# 匹配 article 标签内包含 products 文本的节点
page.locator('article:has-text("products")').click()
# 匹配 article 标签下包含类名为 promo 的 div 标签的节点
page.locator("article:has(div.promo)").click()
Xpath
page.locator("xpath=//button").click()
page.locator('xpath=//div[@class="container"]').click()
其它
# 根据文本匹配,匹配文本内容包含 name 的节点
page.locator('text=name').click()
# 匹配文本内容为 name 的节点
page.locator("text='name'").click()
# 正则匹配
page.locator("text=/name\s\w+word").click()
# 匹配第一个 button 按钮
page.locator("button").locator("nth=0").click()
# 匹配第二个 button 按钮
page.locator("button").locator("nth=-1").click()
# 匹配 id 为 name 的元素
page.locator('id=name')
当进行 click 、fill 等操作时,Playwright 在采取行动之前会对元素执行一系列可操作性检测,以确保这些行动能够按预期进行。
如对元素进行 click 操作之前,Playwright 将确保:
元素附加到 DOM
元素可见
元素是稳定的,因为没有动画或完成动画
元素接收事件,因为没有被其他元素遮挡
元素已启用
即使 Playwright 已经做了充分准备,但是也并不完全稳定,在实际项目中依旧容易出现因页面加载导致事件没有生效等问题,为了避免这些问题,需要自行设置等待。
# 固定等待1秒
page.wait_for_timeout(1000)
# 等待事件
page.wait_for_event(event)
# 等待加载状态
page.get_by_role("button").click()
page.wait_for_load_state()
添加/删除事件
from playwright.sync_api import sync_playwright
def print_request_sent(request):
print("Request sent: " + request.url)
def print_request_finished(request):
print("Request finished: " + request.url)
with sync_playwright() as p:
browser=p.chromium.launch(headless=False)
page=browser.new_page()
# 添加事件 发起请求时打印URL
page.on("request", print_request_sent)
# 请求完成时打印URL
page.on("requestfinished", print_request_finished)
page.goto("https://baidu.com")
# 删除事件
page.remove_listener("requestfinished", print_request_finished)
browser.close()
在 Selenium 的使用中,我们讲到了自动化工具容易被网站检测,也提供了一些绕过检测的方案。这里我们介绍一下 Playwright 的反检测方案。
以 https://bot.sannysoft.com/ 为例,我们分别测试正常模式与无头模式下的检测结果。
正常模式:
无头模式:
可以看到,正常模式下 WebDriver 一栏报红,而无头模式下更是惨不忍睹,基本上所有特征都被检测到了。这些还只是最基本的检测机制,自动化工具的弱点就暴露的很明显了。
与 Selenium 一样,绕过检测主要还是针对网站的检测机制来处理,主要就是在页面加载之前通过执行 JS 代码来修改一些浏览器特征。以无头模式为例:
from playwright.sync_api import sync_playwright
with open('./stealth.min.js', 'r') as f:
js=f.read()
with sync_playwright() as p:
browser=p.chromium.launch()
# 添加 UserAgent
page=browser.new_page(
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
)
# 执行 JS 代码
page.add_init_script(js)
page.goto("https://bot.sannysoft.com/")
page.screenshot(path='example.png')
browser.close()
这里与 Selenium 反检测方案一样,执行 stealth.min.js 来隐藏特征( stealth.min.js 的来源与介绍参考上期文章)。最终结果如下图:
可以看到,与真实浏览器访问基本一致了。
与 Selenium 相比,Playwright 最大的优点就是不需要手动安装驱动,而且它拥有更好的性能与更多的功能。因此 在爬虫领域,Playwright 是更好的选择。
文将介绍使用C#编程语言实现自动登录网页、浏览页面并抓取数据的方法。
1.登录功能:
通过C#编写代码,实现自动模拟用户登录网页的功能。可以使用WebClient类或HttpWebRequest类来发送POST请求,将用户名和密码作为参数传递给服务器,以实现自动登录。
2.页面浏览:
利用C#的WebBrowser控件,可以模拟用户对网页进行浏览操作。可以设置WebBrowser控件的Url属性来加载指定的网页,并使用Navigate方法实现页面跳转。
3.页面元素操作:
在页面加载完成后,可以通过C#代码对页面元素进行操作。例如,可以使用HtmlAgilityPack类库来解析HTML文档,根据元素的XPath或CSS选择器定位到指定的元素,并读取或修改其属性值。
4.数据抓取:
通过分析页面结构和使用合适的选择器,可以用C#代码抓取页面中所需的数据。可以使用正则表达式、XPath或CSS选择器等方式来定位和提取目标数据,并将其保存到变量或数据库中供后续处理。
5.数据处理与分析:
获取到抓取的数据后,可以进行进一步的处理和分析。可以使用C#的数据处理类库,如LINQ或DataTable,对数据进行筛选、排序、统计等操作,以得到所需的结果。
6.定时任务:
利用C#的定时任务功能,可以实现定时自动执行抓取数据的操作。可以使用Timer类或Quartz.NET等工具来设置定时触发器,定期调用抓取数据的代码。
7.异常处理:
在编写自动登录网页并抓取数据的程序时,需要考虑各种异常情况的处理。例如,网络连接异常、页面加载超时、元素定位失败等情况都需要进行相应的错误处理,并给出友好的提示信息。
8.数据存储与展示:
抓取到的数据可以保存到本地文件或数据库中,并通过C#编程实现数据的存储和展示。可以使用ADO.NET来连接数据库并执行相关操作,也可以使用第三方库如Dapper或Entity Framework简化数据库操作。
以上就是使用C#实现自动登录网页、浏览页面并抓取数据的方法。通过这些技术手段,我们可以更高效地获取所需的数据,并进行进一步的处理和分析,为我们提供更多有价值的信息。无论是爬取网页内容还是进行数据挖掘分析,C#都是一个强大而灵活的工具。希望本文能对读者在这方面有所帮助。
、location.href常见的几种形式
①如果页面中自定义了frame,那么可将parent、self、top换为自定义frame的名称,效果是在frame窗口打开url地址。
②此外,window.location.href=window.location.href;和window.location.Reload();都是刷新当前页面。区别在于是否有提交数据。当有提交数据时,window.location.Reload()会提示是否提交,window.location.href=window.location.href;则是向指定的url提交数据.
③用window.open()打开新页面但是用window.location.href=""却是在原窗口打开的.有时浏览器会一些安全设置window.open肯定被屏蔽。例如避免弹出广告窗口。
二、location.href不同形式之间的区别
a.html:
b.html:
c.html:
d.html:
a.html里面嵌着b.html;b.html里面嵌着c.html;c.html里面嵌着d.html
在d.html里面head部分写js:
再次运行a.html,点击那个"跳转"按钮,运行结果贴图二如下:
对比图一和图二的变化,你会发现d.html部分已经跳转到了百度的首页,而其它地方没有发生变化。这也就解释了"本页跳转"是什么意思。
修改d.html里面的js部分为:
分析:我点击的是a.html中嵌套的d.html部分的跳转按钮,结果是a.html中嵌套的c.html部分跳转到了百度首页,这就解释了"parent.location.href是上一层页面跳转"的意思。再次修改d.html里面的js部分为:
运行a.html后,再次点击"跳转"按钮,
你会发现,a.html已经跳转到了百度首页。
分析:我点击的是a.html中嵌套的d.html部分的跳转按钮,结果是a.html中跳转到了百度首页,这就解释了"top.location.href是最外层的页面跳转"的意思。
三、location.href总结
看完上面的讲解之后,在来看看下面的定义你就会非常明白了:
location是window对象的属性,而所有的网页下的对象都是属于window作用域链中(这是顶级作用域),所以使用时是可以省略window。而top是指向顶级窗口对象,parent是指向父级窗口对象。
四、window.location.href和window.open的区别
window.location是window对象的属性,而window.open是window对象的方法window.location是你对当前浏览器窗口的URL地址对象的参考!window.open是用来打开一个新窗口的函数!
在给按钮、表格、单元格、下拉列表和DIV等做链接时一般都要用Javascript来完成,和做普通链接一样,可能我们需要让链接页面在当前窗口打开,也可能需要在新窗口打开,这时我们就可以使用下面两项之一来完成:
window.location或window.open如何指定target?这是一个经常遇到的问题,特别是在用frame框架的时候解决办法:
或
5、window.open用来打开新窗口window.location用来替换当前页,也就是重新定位当前页
用户不能改变document.location(因为这是当前显示文档的位置)。window.location本身也是一个对象。
但是,可以用window.location改变当前文档(用其它文档取代当前文档),而document.location不是对象。服务器重定向后有可能使document.url变动,但window.location.href指的永远是访问该网页时用的URL.大多数情况下,document.location和location.href是相同的,但是,当存在服务器重定向时,document.location包含的是已经装载的URL,而location.href包含的则是原始请求的文档的URL.
6、window.open()是可以在一个网站上打开另外的一个网站的地址window.location()是只能在一个网站中打开本网站的网页
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小编。
*请认真填写需求信息,我们会在24小时内与您取得联系。