Selenium配合chromedriver爬取网页pythonscraping.com/pages/javascript/ajaxDemo.html遇到的问题记录

1 介绍

Selenium是最初用于网站测试的工具,现在广泛用于网络爬虫。配合某个浏览器工具,其能自动加载网页,获取所需的数据,也能获取网页快照和判断某个事件是否在网站上发生。

利用urllib.request.urlopen、或者requests.get()等方法爬取网页有一个不适用的场景是:当网页是一个JavaScript驱动时。这时得到的是预加载的内容,而不是自己真正想要的内容。如果此时,我们用浏览器手工看到的网页内容,将会与爬取的html代码不一致。在这种情况下Selenium能大显身手。

Selenium的安装方法简单,在Python中用以下安装命令:

pip install selenium

其官方网站有对其使用方法的详细介绍讲解。Selenium本身是一个很好的爬虫工具,但其并不包含自身的Web浏览器,需要配合第三方浏览器使用。PhantomJS是一个无头浏览器(headless browser),它能够将网页加载到内存中,然后做各种有趣的事情。前几年它广泛配合Selenium使用,但最近Selenium已不推荐使用它了。在书籍《Web Scraping with Python: Collecting more data from the Modern Web》1的第二版的GitHub上公布的源代码已使用chromedriver作为第三方浏览器。chromedriver可以从其国内的镜像网站下载,我在win7电脑上安装的chrome版本为84.0.4147.135 (正式版本) (32 位) (cohort: Stable),所以我在该镜像网站上选取一个较为接近的版本,如下图:
我电脑下载的chromedriver版本
下载完成后,解压到Python项目的当前文件夹或其他路径,就可以配合Selenium使用了。

下面讲解书籍《Web Scraping with Python: Collecting more data from the Modern Web》1的第二版的GitHub上公布的源代码:

# ScrapeJavaScript.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time

chrome_options = Options()
chrome_options.add_argument("--headless")
driver = webdriver.Chrome(
    executable_path='chromedriver', 
    options=chrome_options)
driver.get('http://pythonscraping.com/pages/javascript/ajaxDemo.html')
time.sleep(3)
print(driver.find_element_by_id('content').text)
driver.close()

遇到的问题及相关解决过程。

2 相关问题及解决过程记录

问题1

运行上述代码,得到如下结果:

(.scenv) E:\StudyCard\WebScrape\WSwP2ed>python ScrapeJavaScript.py
DevTools listening on ws://127.0.0.1:6515/devtools/browser/88e3476a-7b6e-4e22-8b
b8-ff38a2e54cdc
This is some content that will appear on the page while it’s loading. You don’t
care about scraping this.

显然,根据书上的阐述,抓取返回的内容不对。经过试探,将代码改为(即删除代码行chrome_options.add_argument("--headless")):

# ScrapeJavaScript.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time

chrome_options = Options()
driver = webdriver.Chrome(
    executable_path='chromedriver', 
    options=chrome_options)
driver.get('http://pythonscraping.com/pages/javascript/ajaxDemo.html')
time.sleep(3)
print(driver.find_element_by_id('content').text)
driver.close()

运行时,会自动弹出Chrome浏览器,如下图:
自动弹出的浏览器
运行完后chrome浏览器会自动关闭。此时cmd中的运行结果为:

(.scenv) E:\StudyCard\WebScrape\WSwP2ed>python ScrapeJavaScript.py
DevTools listening on ws://127.0.0.1:6638/devtools/browser/9005ed67-d9d1-40cd-99
f0-99f106bc068d
[0823/092911.775:ERROR:gl_surface_egl.cc(699)] EGL Driver message (Error) eglQue
ryDeviceAttribEXT: Bad attribute.
[0823/092911.778:ERROR:gl_surface_egl.cc(699)] EGL Driver message (Error) eglQue
ryDeviceAttribEXT: Bad attribute.
[0823/092911.785:ERROR:gl_surface_egl.cc(699)] EGL Driver message (Error) eglQue
ryDeviceAttribEXT: Bad attribute.
[0823/092911.787:ERROR:gl_surface_egl.cc(699)] EGL Driver message (Error) eglQue
ryDeviceAttribEXT: Bad attribute.
[0823/092912.464:ERROR:gl_surface_egl.cc(699)] EGL Driver message (Error) eglQue
ryDeviceAttribEXT: Bad attribute.
Here is some important text you want to retrieve!
A button to click!

可以看出,我们爬取到了正确结果,但是在正确的文本信息前面出现了许多错误提示。

问题2 gl_surface_egl.cc(699)] EGL Driver message (Error) eglQueryDeviceAttribEXT: Bad attribute.错误信息的消除

通过在网上搜索相关的解决方案,stackoverflow网站上的帖子有解决方案,遂用之,增加一行代码chrome_options.add_argument('--disable-gpu'),如下:

# ScrapeJavaScript.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time

chrome_options = Options()
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(
    executable_path='chromedriver', 
    options=chrome_options)
driver.get('http://pythonscraping.com/pages/javascript/ajaxDemo.html')
time.sleep(3)
print(driver.find_element_by_id('content').text)
driver.close()

cmd上的运行结果如下:
在这里插入图片描述
但此时会自动弹出chrome浏览器的运行界面,这样会延长时间。那么如何在headless模式得到正确的爬虫结果呢?

问题3 如何在headless模式得到正确的爬虫结果

经过分析,上述代码中的等待时间太短,我将等待时间改为5秒时,得不到正确结果。然后改为等待时间8秒,最终得到正确的爬虫结果。因为浏览器执行JavaScript时,需要一定的时间,若等待的时间不够,则页面仍然是预加载前的页面,当然得不到正确的结果。在headless模式下,能得到正确爬虫结果的代码如下:

# ScrapeJavaScript.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time

chrome_options = Options()

chrome_options.add_argument("--headless")
#chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(
    executable_path='chromedriver', 
    options=chrome_options)
driver.get('http://pythonscraping.com/pages/javascript/ajaxDemo.html')
time.sleep(8)
print(driver.find_element_by_id('content').text)
driver.close()

cmd中的运行结果为:
正确运行结果
此时,Chrome浏览器也没自动化弹出、运行和关闭。

总结

爬虫技术牵涉的问题很多,在学习的时候要多思考。我们解决问题的时候,可能会引出另一个问题,这就需要我们保持一个渴望求知的状态,将出现的问题一个一个攻克,最终方能加深对问题的理解。


  1. Ryan Mitchell. Web Scraping with Python: Collecting more data from the Modern Web. 2ed, O’Reilly, 2018. ↩︎ ↩︎

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用 SeleniumChromeDriver 进行时,有时会遇到浏览器错误,例如 ChromeDriver 版本与 Chrome 版本不匹配、ChromeDriver 可执行文件路径错误等。以下是一些常见的解决方法: 1. 确认 ChromeDriver 版本与 Chrome 版本匹配。可以通过在 Chrome 地址栏输入 `chrome://version/` 查看 Chrome 版本,然后到 ChromeDriver 官网下载相应版本的 ChromeDriver。 2. 指定 ChromeDriver 可执行文件路径。可以通过实例化 ChromeDriver 时传递 `webdriver.chrome.driver` 参数来指定 ChromeDriver 的可执行文件路径。例如: ```python from selenium import webdriver chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--disable-dev-shm-usage') # 指定 ChromeDriver 可执行文件路径 driver_path = 'path/to/chromedriver' driver = webdriver.Chrome(executable_path=driver_path, chrome_options=chrome_options) # 访问页面 driver.get('https://www.xiaohongshu.com/explore/645874a800000000120338d6') ``` 3. 禁用 Chrome 浏览器的一些安全特性。可以通过在实例化 ChromeDriver 时传递 `--disable-web-security` 和 `--allow-running-insecure-content` 参数来禁用 Chrome 浏览器的一些安全特性。例如: ```python from selenium import webdriver chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--disable-dev-shm-usage') chrome_options.add_argument('--disable-web-security') chrome_options.add_argument('--allow-running-insecure-content') driver = webdriver.Chrome(chrome_options=chrome_options) # 访问页面 driver.get('https://www.xiaohongshu.com/explore/645874a800000000120338d6') ``` 这些方法可能会绕过浏览器错误,但同时也会降低安全性,请谨慎使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值