内容导读
- 使用逆向分析爬取动态网页
- 使用Selenium库爬取动态网页
一、使用逆向分析爬取动态网页
动态网页中数据需要通过逆向分析的思路,借助浏览器中的开发者模式,定位目标数据所在的资源,并确定目标数据所在的URL。
爬取动态网页步骤:
判别网页的类型。
使用Chrome开发者工具的“网络”面板定位目标信息所在位置。
使用Chrome开发者工具确定目标信息所在网址。
使用Requests库发送请求,获取响应内容。
使用JSON格式对响应内容进行解析,提取目标信息。
1、判别网页类型
获取“新书推荐”栏中计算机类的8本图书的名称,需要先确定目标内容是静态内容还是动态内容,基本步骤如下:
(1)在浏览器中右击,选择“查看网页源代码”选项,得到当前页面的静态源代码。
(2)使用组合键“Ctrl+F”,在当前网页源代码中进行搜索,搜索的内容为部分目标文字。
(3)检索到的匹配次数为0次,即通过静态的网页源代码无法定位到目标内容,目标内容采用了动态加载的方法,需要采用动态网页爬取的方法来获取。
2、获取动态网页信息
在确认网页是动态网页之后,需要获取在网页响应中由JavaScript动态加载生成的信息。在Chrome浏览器中查找网页“新书推荐”栏中图书名称所在资源,基本步骤如下。
(1)按“F12”键打开网页“https://www.ptpress.com.cn”的Chrome开发者工具,选择“面板网络”,并按“F5”键进行页面刷新,加载各项资源。
(2)打开“网络”面板后,会发现有很多响应。
在“网络”面板中,“Fetch/XHR”是AJAX(Asynchronous JavaScript and XML,异步JavaScript和XML技术)中的概念,表示XML-HTTP-request对象,一般JavaScript加载的文件隐藏在“JS”或“Fetch/XHR”中。
通过查找可发现,网页https://www.ptpress.com.cn通过JavaScript加载的文件在“Fetch/XHR”上。
在开发者工具中,可以通过单击“Fetch/XHR”对加载资源进行过滤,筛选XML-HTTP-request对象。
(3)“新书推荐”栏的信息会在“Fetch/XHR”的“预览”标签中显示。
在“网络”面板的Fetch/XHR中,查看“getRecommendBookListForPortal”资源的“预览”信息,可以看到推荐的图书名称。
3、网页内容爬取实例
爬取“https://www.ptpress.com.cn”首页“新书推荐”栏下的图书名称,基本步骤如下。
(1)单击“getRecommendBookListForPortal”资源的“标头”标签,找到“请求网址”。
(2)使用Requests库向找到的请求网址发送请求,获得响应内容。
(3)使用JSON格式,将响应内容中的图书名称提取出来。
二、使用Selenium库爬取动态网页
动态网页内容除了可以采用逆向分析方法爬取之外,还可以使用Selenium库爬取。
Selenium库是一个功能非常强大的自动化测试工具,能模拟浏览器的行为,支持多种主流浏览器,可以获取到页面动态加载之后的内容。
2.1 下载浏览器驱动
在使用Selenium库启动浏览器时,需要下载、安装对应的浏览器驱动,下面以Chrome浏览器驱动文件下载和安装为例介绍基本步骤。
(1)确定当前浏览器的版本号,可以在Chrome浏览器中通过“关于Google Chrome”查看版本号,如下图所示。
(2)在Chrome浏览器驱动的官网下载对应浏览器版本和当前操作系统版本的驱动,并将驱动文件放置到系统路径中。
当前浏览器版本号为108.0.5359.72,驱动版本号几乎没有和浏览器版本完全一致的。
选择尽可能相近的即可(至少保证主版本号一致),本任务选择的驱动版本号为108.0.5359.71。
进入该驱动版本对应目录下,选择对应操作系统的文件进行下载。
根据操作系统版本,此处下载chromedriver_win32.zip。
(3)将下载的压缩文件解压,得到chromedriver.exe驱动文件,将chromedriver.exe驱动文件放置到安装Python的根目录(与python.exe文件同一目录)下。
使用Selenium可以模拟用户的行为,操控浏览器进行相应的动作。
2.2 元素选取
(1)单个元素选取
在Selenium 4.7.2版本中,find_element_by_xx用法已被废弃,当前使用find_element()方法实现单个元素选取功能。find_element()方法的基本语法格式如下。
方法定位策略列表如下:
find_element()方法返回的结果是一个WebElement类型的对象,如果需要提取该对象标签中的文本信息,那么需要使用该对象的text属性。
如果需要提取该对象标签的某个属性值,那么需要用到get_attribute()方法。
除了使用Xpath定位之外,还可以使用其他的方式定位,如:browser.find_element(By.CSS_SELECTOR, 'div.row>a:nth-child(1)')、browser.find_element(By.LINK_TEXT, '首页')等。
(2)多个元素选取
多个元素的选取方法find_elements()与单个元素的选取方法find_element()的两个参数作用是一致的,find_elements()方法的基本语法格式如下,其中,参数by的取值及说明可以参照前面的表。
find_elements()方法返回的结果是一个列表,列表中的每个元素是WebElement类型的对象。
当使用find_element()方法定位单个元素时,若有多个符合条件的元素,则只返回符合条件的第一个元素;若没有符合条件的元素被定位到,则程序会报错。
当使用find_elements()方法定位多个元素时,返回的是符合条件的元素列表,若没有符合条件的元素,则返回空列表。
使用find_elements()方法定位多张图片,并使用screenshot_as_png()方法对每个WebElement对象所选中的图片标签的对应图片进行截图保存。
如果需要通过<img>标签的src属性值的对应网址,将图片保存下来,那么通常需要借助Requests库发送请求,将得到的响应的content值保存下来,即可得到原图片。
2.3 元素交互
使用find_element()方法定位单个元素或find_elements()方法定位多个元素后,可以对不同WebElement对象进行不同交互操作。
例如,对于可单击的<a>标签,进行单击操作;对于可以输入文本的<input>标签,进行输入文字的操作等。
(1)单击
在网页中经常有一些按钮、超链接可以单击,Selenium库可以通过click()方法对定位到的元素进行单击。
(2)输入文字
在网页中,各种文本输入框十分常见,如各购物网站中用户可以根据自己的需求进行检索。
在网页“https://www.ptpress.com.cn/”的首页也存在文本输入框,用于检索图书。
通过Selenium库输入文字,需要在定位到文本输入框元素的前提下,使用send_keys()方法,向该文本输入框中输入内容。
在输入结束后,通过使用“Enter”键或单击“搜索”按钮进行搜索。
在输入文字之后,若需要从使用“Enter”键进行搜索,则需要加载Keys模块。
2.4 页面操作
1、页面交互
使用Selenium库打开的浏览器窗口大小是默认的,可以采用maximize_window()方法实现浏览器窗口的最大化。maximize_window()方法的基本语法格式如下。
WebDriver.maximize_window()
在浏览器打开后,即使程序执行完成,浏览器仍不会自动关闭,此时,需要使用quit()或close()方法主动关闭浏览器。
quit()方法表示关闭整个浏览器,即不管浏览器打开多少个窗口,都全部关闭。
close()方法表示关闭当前窗口,如果当前浏览器仅打开一个窗口,那么效果和quit()方法的效果一样。
quit()方法与close()方法的基本语法格式如下。
WebDriver.quit()
WebDriver.close()
网页操作中经常需要滚动鼠标,浏览页面中其他内容,页面滚动操作可以通过Selenium库中的execute_script()方法执行JavaScript代码实现,该方法的基本语法格式如下。
在对网页进行操作时,可以通过save_screenshot()方法对当前标签页面进行截图。save_screenshot()方法的基本语法格式如下。
2、页面切换
当单击网页链接时,浏览器经常会以新的窗口呈现链接对应的内容。
在Selenium库中,需要通过窗口切换来控制当前窗口,否则默认当前窗口是一直是最开始打开的窗口。
而窗口切换需要先获取到当前浏览器的所有窗口的句柄,并返回一个窗口句柄列表,然后通过WebDriver.switch_to.window()方法切换到指定窗口。
当使用浏览器加载页面时,一般要等待页面元素加载完成后,才能执行某些操作,否则会出现找不到某元素等错误。
在这种要求下,某些场景需要加入等待时间。
根据等待方式的不同,可以将页面等待划分为强制等待、隐式等待和显式等待。
3、页面等待
当使用浏览器加载页面时,一般要等待页面元素加载完成后,才能执行某些操作,否则会出现找不到某元素等错误。
在这种要求下,某些场景需要加入等待时间。
根据等待方式的不同,可以将页面等待划分为强制等待、隐式等待和显式等待。
(1)强制等待
利用time模块中的sleep()方法实现,不管页面是否加载完成,都要强制等待一段时间,时间到达后,才会执行后续的代码。但使用此等待方式,会比较呆板,影响代码的执行效率。
(2)隐式等待
设置一个隐式等待时间后,如果在这个时间内,网页加载完成,那么会执行下一步操作,否则会一直等到超时,才执行下一步操作。
隐式等待方式也存在弊端,即用户所需的元素已加载完成,而其他元素加载较慢,仍要等待所有元素加载完成后,才会执行下一步操作,时间上有所增加。注意:当使用隐式等待时,仅需要对某个窗口设置一次。
(3)显式等待
显式等待需要用到WebDriverWait类,其基本语法格式如下。
WebDriverWait要结合该类的unitl()和unitl_not()方法来使用,还需要导入一个类expected_conditions,用于判断预期条件是否达成。
expected_conditions类的常见判断方法如表。
续上表:
续上表:
更多精彩内容请关注本站!