最近想研究一下收集数据,因为网上太多例子是python的了,其实对这个不熟,但遇到的问题和想解决的问题如下:
一、模拟浏览器操作,然后抓取DevTools中返回的数据,其实是可以直接用ajax直接取,但如果页面更新或者后台有桩容易被识别到拉黑名单。
二、如何操作浏览器里的页面,我不关注,那个资料太多了。
三、网上的例子都是跑一遍就关掉了,无法持续抓取,研究了一下多线程和回调。
四、在研究selenium之前,研究过miniblink,这个其实还可以,开源,唯一对这个不放心的就是稳定性,因为有些页面打开后,超级卡。
五、还想过开发chrome的devtools扩展,然后跟程序来交互,因为selenium刚开始弄了一下,好多坑,不过想想写的扩展,未必也稳定,也不好控制。
六、研究过browsermob-proxy,通过代理来抓包,用java写的,感觉这个就是垃圾,捣鼓了一天,连程序都没有跑起来,直接就扔了,何况代理还有https的问题也是个老大难。
七、研究了一下Chrome DevTools Protocol 之后(https://chromedevtools.github.io/devtools-protocol/tot/Log/ ) 下决心弄selenium。
八、以某网站的获取ETA数据为例:
#启动chrome模块
import time import json from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities import global_dict def _init(): caps = DesiredCapabilities.CHROME caps['loggingPrefs'] = { 'browser':'ALL', 'performance':'ALL', } caps['perfLoggingPrefs'] = { 'enableNetwork' : True, 'enablePage' : False, 'enableTimeline' : False } option = webdriver.ChromeOptions() option.add_argument('--no-sandbox') #option.add_argument('--headless') option.add_argument("--disable-extensions") option.add_argument("--allow-running-insecure-content") option.add_argument("--ignore-certificate-errors") option.add_argument("--disable-single-click-autofill") option.add_argument("--disable-autofill-keyboard-accessory-view[8]") option.add_argument("--disable-full-form-autofill-ios") option.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:55.0) Gecko/20100101 Firefox/55.0') option.add_experimental_option('w3c',False) option.add_experimental_option("detach", True) option.add_experimental_option('perfLoggingPrefs',{ 'enableNetwork':True, 'enablePage':False, }) driver = webdriver.Chrome(options=option,desired_capabilities=caps) windows = driver.window_handles # 获取所有窗口句柄 for i in windows: driver.switch_to.window(i) if(driver.title == "设置"): driver.close() break; driver.switch_to.window(driver.window_handles[0]) time.sleep(0.5) return driver
#主模块 import time import global_dict import RunChrome from FindLog import * from threading import Thread def call_back(method,logdata): if (method == 'Network.responseReceived'): requestId = logdata['params']['requestId'] urls= logdata['params']['response']['url'] mimeType= logdata['params']['response']['mimeType'] #print(urls) try: if (urls.find("https://xxxxx/")>=0): #if (mimeType.find("text")>=0 or mimeType.find("html")>=0 or mimeType.find("json")>=0): response_body = driver.execute_cdp_cmd('Network.getResponseBody',{'requestId': requestId}) print("================find eta======================") print(response_body['body']) except: print('response.body is null') global_dict._init() driver=RunChrome._init() driver.get('https://xxxxx/') STR_READY_STATE = '' # 而直接操作页面就需要类似于下面的代码等待页面加载完成 while STR_READY_STATE != 'complete': time.sleep(0.1) STR_READY_STATE = driver.execute_script('return document.readyState') time.sleep(1) global_dict.set_value("thread_run",True) a = logNetWork(call_back) t = Thread(target=a.task, args=(a,driver)) # 创建线程 t.start() # 启动线程 while True: ip=input("input a int") if (ip=="0"): global_dict.set_value("thread_run",False) time.sleep(1) break driver.close() driver.quit ()
import time import json from selenium import webdriver import global_dict class logNetWork(object): def __init__(self, callback): self.mycallback = callback @staticmethod def task(self,driver): sign= global_dict.get_value("thread_run") while sign: perfs = driver.get_log("performance") #print("===============start==============" + str(perfs.__len__()) +"===" +time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime())) for row in perfs: log_data = row log_json = json.loads(log_data['message']) log = log_json['message'] self.mycallback(log['method'],log) time.sleep(0.1) #print("===============end==============" + str(perfs.__len__()) +"===" +time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime())) time.sleep(0.5) sign= global_dict.get_value("thread_run")