Python使用Selenium Webdriver爬取网页所有内容

一、为什么我抓不到网页的全部html内容

有时候,我们在用urllib或者requests库抓取页面时,得到的html源代码和浏览器中看到的不一样。这将是我们面临的一个非常常见的问题。现在网页越来越多地采用Ajax、前端模块化工具来构建,整个网页可能都是由JavaScript渲染出来的,也就是说原始的HTML代码可能就是一个空壳,例如:

<!DOCTYPE html>
<html>
    
    <head>
        <meta charset="UTF-8">
        <title>
            this is a demo
        </title>
    </head>
    
    <body>
        <div id="container">
        </div>
    </body>
    <script src="app.js">
    </script>

</html>

body节点里面只有一个id为container的节点,但是需要注意在body节点后引入了app.js, 它便负责整个网站的渲染。

在浏览器中打开这个页面时,首先会加载这个HTML内容,接着浏览器会发现其中引入了一个app.js文件,然后便会接着去请求这个文件,获取到该文件后,便会执行其中的JavaScript代码,而JavaScript则会改变HTML中的节点,向其中添加内容,最后得到完整的页面。

但是在用urllib或者requests等库请求当前页面时,我们得到的只是这个HTML代码,它不会帮助我们去继续加载这个JavaScript文件,这样也就看不到浏览器中的内容了。

而且,JavaScript动态渲染的页面可不止Ajax这一种,还有其他各种原因会导致我们得到的源代码和浏览器中看到的不一样。

对于抓不到全部html内容的情况,我们能采取什么应对措施呢,本文介绍一种可行的方法,就是通过Selenium webdriver来模拟浏览器运行的方式,这样就可以做到在浏览器中看到是什么样,抓取的源码就是什么样,也就是可见即可爬。这样,我们就不用再去管网页内部的JavaScript用了什么算法渲染页面,也不用管网页后台的Ajax接口到底有哪些参数。所有的这些,都交给Selenium webdriver来帮我们完成。

二、Selenium的基本使用

Selenium是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬。对于一些JavaScript动态渲染的页面来说,此种抓取方式非常有效。

Selenium webdriver的安装和基本使用方法,可以参考另一篇文章。
Python使用Selenium WebDriver的入门介绍及安装教程

Selenium的官方网站:
Selenium WebDriver

一些基本的用法,此处不再赘述。

三、使用Selenium抓取全部HTML

先看使用requests库直接提取到的代码,可以发现并不是完整的:

20221214220011

使用Selenium拿到的html代码,可以看到已经可以通过src属性提取到图片的url:

20221214220124

示例代码如下,详细的解读可以参考每一步的注释:

from selenium.webdriver import Firefox, FirefoxOptions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

class ContentPageParser():
    def __init__(self, content_page_url) -> None:
        self.content_url = content_page_url # 抓取content_page_url页面上全部的图片url
        self.img_src = []                   # 保存当前页面上所有的图片url
    
    def visit_content_page_with_firefox(self):
        option = FirefoxOptions()
        # 设置浏览器为无头模式,使用过程中不会弹出浏览器页面
        option.headless = True
        self.driver = Firefox(options=option)
        try:
            # 打开待抓取的url页面
            self.driver.get(self.content_url)
            # 设置灵活等待,最长等待10s,轮询间隔为1s
            wait = WebDriverWait(self.driver, timeout=10, poll_frequency=1)
            # 使用css选择器进行元素定位,直到元素可见为止
            wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'img[class="showimg"]')))
            # 使用css选择器查找所有元素
            imgs = self.driver.find_elements(By.CSS_SELECTOR, 'img[class="showimg"]')
            # 提取所有图片的url
            for img in imgs:
                self.img_src.append(img.get_attribute('src'))
        except Exception as e:
            print(repr(e))
        finally:
            # 关闭webdriver
            self.driver.close() 
    
    def get_img_src(self):
        return self.img_src
    
if __name__ == '__main__':
    content_parser = ContentPageParser('https://xxx/content_48495.html')
    content_parser.visit_content_page_with_firefox()
    img = content_parser.get_img_src()
    print(img)
  • 5
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

smart_cat

你的鼓励将是我写作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值