小隐的博客

人生在世,笑饮一生
随笔 - 304, 文章 - 0, 评论 - 349, 阅读 - 50万
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

selenium+webdriver+python 收集数据

Posted on   隐客  阅读(306)  评论(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模块<br>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")

  

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
QQ交流
点击右上角即可分享
微信分享提示