使用Selenium 爬取网页内容时,异步加载、js加密、动态Cookie等问题都非常简单的能够获取或提交表单。
很多网站数据都是通过json 结构来交互,直接分析json 结构数据不但全而且很好解析,这比解析 html 网页简单很多。而且很多时候一些接口返回的关键信息不在 html 网页上显示,直接通过 selenium 获得的这些网页就没有这些信息。
selenium + webdriver虽然能够定位DOM元素、操作网页、获取网页等,但是 Selenium 只能处理“结果”,它无法得知浏览器请求的数据接口信息。若是能够像浏览器 Network 那样获取所有接口的请求和返回信息,就能够获取一些关键信息。
本文使用BrowserMob-Proxy 来解决这个问题。 使用 webdriver 通过 proxy 访问网络,再收集 proxy 端的请求和返回内容,从而获取到数据,而这个 proxy 就类似于 fiddler 抓包软件。
1、安装Browsermob-Proxy
(1)、 pip3 install BrowserMob-Proxy
(2)、 下载java端BrowserMob-Proxy包:http://bmp.lightbody.net/
(3)、 安装java8环境
2、实战
这里以 百度 为例。使用 Selenium + Webdriver + Browsermob-Proxy 获取接口返回的数据。
from browsermobproxy import Server
from selenium import webdriver
import time
import pprint
class ProxyManger:
__BMP = "D:/AzRjN/browsermob_proxy/browsermob-proxy-2.1.4/bin/browsermob-proxy.bat"
def __init__(self):
self.__server = Server(ProxyManger.__BMP)
self.__client = None
def start_server(self):
self.__server.start()
return self.__server
def start_client(self):
self.__client = self.__server.create_proxy(params={"trustAllServers": "true"})
return self.__client
@property
def client(self):
return self.__client
@property
def server(self):
return self.__server
if __name__=="__main__":
# 开启Proxy
proxy = ProxyManger()
server = proxy.start_server()
client = proxy.start_client()
# 配置Proxy启动WebDriver
options = webdriver.ChromeOptions()
options.add_argument("--proxy-server={}".format(client.proxy))
options.add_argument('--ignore-certificate-errors')
chromePath = r"D:\AzRjN\anaconda3_7\envs\demo36\Lib\site-packages\selenium\webdriver\chrome\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chromePath, chrome_options=options)
# 获取返回的内容
client.new_har("baidu.com")
driver.get("https://www.baidu.com/")
time.sleep(3)
newHar = client.har
pprint.pprint(newHar)
server.stop()
通过 Har 就能获取浏览器所有的请求,然后过滤出数据接口就OK,而且拿到的结构和在浏览器开发者模式 Network中看到的是一样的。