小隐的博客

人生在世,笑饮一生
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

selenium+webdriver+python 收集数据

Posted on 2021-06-22 20:08  隐客  阅读(299)  评论(0编辑  收藏  举报

最近想研究一下收集数据,因为网上太多例子是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")
 

  

QQ交流