问题
在进行网络数据采集(爬虫)时,可能会遇到这样的情况:需爬取的网站为动态网站。
举例来说,在网页界面,如果使用鼠标进行悬停、点击某处等操作,可以 “唤出” 额外的内容(如图1,弹窗中包含文字和图片信息),此时这些额外内容的 HTML 源码从隐藏变为可见,但网页的 URL 却未改变。
若想采集这些 “隐藏的信息” ,用于爬取静态网页的 requests 就力不从心了。此时可以使用 selenium 来模拟用户使用浏览器的操作,以获取 “隐藏的信息” 。
图1:点击知乎主页的 “私信”,即可得到一个包含文字和图片信息的弹窗
解决方案
1.1 文字信息
功能:点击网页中某处后出现弹窗,获取弹窗中的文字信息
在网上下载 selenium 适用于 Firefox 浏览器的驱动文件 geckodriver.exe,并将其存储至 python 项目的路径中。
- 下载地址:Firefox 浏览器驱动文件
导入本例中所需的包和模块:
- 注:对于 pyautogui,直接在 cmd 中输入 “pip install pyautogui” 可能会安装失败。可以在 PyAutoGUI 官网 下载安装程序,再在 cmd 中进入该文件的目录,执行 “python setup.py install” 即可安装成功。
import pandas as pd from selenium import webdriver import os, time, random from selenium.webdriver.common.action_chains import ActionChains import pyautogui
利用 selenium 中的 webdriver 模块,打开 Firefox 浏览器并进入网页。此时会自动弹出一个浏览器界面,可以自动/手动进行操作。
driver = webdriver.Firefox() # 驱动打开Firefox浏览器 url = '请输入爬取网站的URL' driver.get(url) # 驱动进入网页 time.sleep(3) # 设置爬虫时间间隔:IP保护
- warning:网页若需要输入验证码、登录账号,则需手动操作完毕后,再运行后续代码。
利用 pandas 创建一个 dataframe,用来保存爬取到的信息。
df = pd.DataFrame(columns=['']) # 请在 columns 参数后输入列名
获取弹窗中的文字信息:
# 请额外加入循环代码,以自动获取数据: xpath = '点击按钮的xpath' xpath_info = '弹窗中显示的文字信息的xpath' xpath_close = '弹出窗口关闭按钮的xpath' try: driver.find_element_by_xpath(xpath).click() # 驱动点击按钮 text = driver.find_element_by_xpath(xpath_info).text # 获取数据 driver.find_element_by_xpath(xpath_close).click() # 驱动关闭按钮 time.sleep(random.random() * 3) # IP保护 except Exception as e: print(repr(e)) driver.quit() # 关闭所有浏览器窗口
输出表格数据:
df.to_excel('文件存储位置' + os.sep + '文件名.xlsx', index=False) # 数据输出
1.2 图片信息
功能:弹窗中存在图片信息,需要右键点击,并保存至本地
- 打开浏览器及网页,手动输入验证码、进行账号登录等操作同上。此处不再赘述。
右键点击图片,并保存至本地默认存储位置:
- warning:请运行下面循环后,迅速将界面切换至驱动打开的 Firefox 浏览器界面(保持浏览器界面为当前窗口)!否则图片无法保存!
xpath = '图片的xpath' name = '图片名称' # 请额外加入循环代码,以自动获取数据: try: context_click = driver.find_element_by_xpath(xpath) time.sleep(2) ActionChains(driver).context_click(context_click).perform() # 实现点击鼠标右键 time.sleep(1) pyautogui.typewrite(['v']) # 敲击V进行保存 time.sleep(1) pyautogui.typewrite(name) # 重命名 time.sleep(1) pyautogui.typewrite(['enter']) # 确定保存 time.sleep(1) pyautogui.typewrite(['enter']) pyautogui.typewrite(['enter']) # 电脑存在bug,敲击一次enter有时无法保存,因此连按3次 time.sleep(random.random() * 3) # IP保护 except Exception as e: print(repr(e))
讨论
- 本文代码未涉及到反爬虫问题。在爬取某些网站时,可能需要采取反爬虫措施。
- 本文代码仅解决了 “鼠标点击某处,出现弹窗,需获取其中信息” 的问题。仍然存在其他的动态网页形式,如滚动产生新数据(信息流)等形式,可参考 selenium 的其他用法。
参考
注:转载请注明出处
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。