• Python 使用BrowserMob Proxy + Selenium 获取Ajax加密数据


    BrowserMob Proxy,简称 BMP,它是一个 HTTP 代理服务,我们可以利用它截获 HTTP 请求和响应内容。

    第一步:先安装 BrowserMob Proxy 的包。

    pip install browsermob-proxy

     第二步:下载 browsermob-proxy 的二进制文件,用于启动 BrowserMob Proxy。

    下载地址:https://github.com/lightbody/browsermob-proxy/releases

    第三步:测试。

    from browsermobproxy import Server
    
    
    # 启动代理, 修改下载的文件路径
    server = Server(r'F:BrowserMobProxyrowsermob-proxy-2.1.4inbrowser-mob-proxy.bat') 
    server.start()
    proxy
    = server.create_proxy()
    print('proxy', proxy.proxy)

    注意:若报错,可查看server.log中的信息。如果没有装java,自行百度安装java,配置java环境,cmd输入java和javac测试是否配置成功。

    第四步:找个网站试试。

    # _*_ coding:utf-8 _*_
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from browsermobproxy import Server
    import time
    import json
    
    
    # 启动代理
    server = Server(r'C:Program Filesrowser-mob-proxy-2.1.4inrowser-mob-proxy.bat')
    server.start()
    proxy = server.create_proxy()
    
    # 启动浏览器
    chrome_options = Options()
    chrome_options.add_argument('--ignore-certificate-errors')
    chrome_options.add_argument('--proxy-server={0}'.format(proxy.proxy))
    # chrome_options.add_argument('--headless')  # 无头模式
    browser = webdriver.Chrome(options=chrome_options)
    
    # 监听结果
    url = '*********************'
    proxy.new_har(options={
            'captureContent': True,
            'captureHeaders': True
        })
    browser.get(url)
    time.sleep(2)
    for i in range(3):
        print(f'正在点击第{i+1}页')
        browser.find_element_by_id('nextPage').click()
        time.sleep(0.2)
        # 读取结果
        result = proxy.har
        for entry in result['log']['entries']:
            request = entry['request']
            response = entry['response']
            # 判断数据所在url并解析数据
            if '/****/****' in request['url']:
                text = response['content']['text']
                text_dict = json.loads(text)
                content_list = text_dict['list']
                for content in content_list:
                    name = content['mc']
                    print(name)
    time.sleep(1)
    # 关闭代理和浏览器
    proxy.close()
    browser.close()

    也可以封装一下,代码走起:

    # _*_ coding:utf-8 _*_
    import os
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from browsermobproxy import Server
    import time
    import json


    class BaseFramework(object):

    def __init__(self):
    # 修改下载的文件路径
    self.server = Server(r'F:BrowserMobProxyrowsermob-proxy-2.1.4inrowser-mob-proxy.bat')
            self.server.start()
    self.proxy = self.server.create_proxy()
    chrome_options = Options()
    chrome_options.add_argument('--ignore-certificate-errors')
    chrome_options.add_argument('--proxy-server={0}'.format(self.proxy.proxy))
    chrome_options.add_argument('--headless') # 无头模式
    self.browser = webdriver.Chrome(options=chrome_options)

    def process_request(self, request, response):
    pass

    def process_response(self, response, request):
    pass

    def run(self, func, *args):
    self.proxy.new_har(options={
    'captureContent': True,
    'captureHeaders': True
    })
    func(*args)
    result = self.proxy.har
    for entry in result['log']['entries']:
    request = entry['request']
    response = entry['response']
    self.process_request(request, response)
    self.process_response(response, request)

    def __del__(self):
    self.proxy.close()
    self.browser.close()


    class Framework(BaseFramework):

    def load(self, url):
    self.browser.get(url)
    time.sleep(3)

    def process_request(self, request, response):
    pass

    def process_response(self, response, request):
    # print(request['url'])
    # 找到你所需数据的url即可快乐的解析数据了
    if '/item/timemap/cn/' in request['url']:
    try:
    text = response['content']['text']
    text_dict = json.loads(text)
    data_result = text_dict['data']
    except KeyError:
    print('----KeyError: text----')
    return
    name = data_result['name'] # 姓名
    id_name = name_id + '_' + name
    print(id_name)
    time_map_list = data_result['timeMap']
    if time_map_list:
    time_map_dict = {}
    for i in range(len(time_map_list)):
    time_map = time_map_list[i]
    time_map_dict[str(i)] = time_map
    else:
    return
    path = f'./****/{id_name}.json'
    if os.path.exists(path):
    print(f'------{id_name}--已存在------')
    return
    with open(path, 'w', encoding='utf-8') as f:
    f.write(json.dumps(time_map_dict, ensure_ascii=False, indent=4))


    if __name__ == '__main__':
    Framework = Framework()
    id_list = ['********']
    for name_id in id_list:
    url = "************************"
    Framework.run(Framework.load, url)

    结果如下:

    解释解释:

    代码一共分了四步:

    •第一步便是启动 BrowserMob Proxy,它会在本地启动一个代理服务,这里注意 Server 的第一个参数需要指定 BrowserMob Proxy 的可执行文件路径,这里我就指定了下载下来的 BrowserMob Proxy 的 bin 目录的 browsermob-proxy 的路径。
    •第二步便是启动 Selenium 了,它可以设置 Proxy Server 为 BrowserMob Proxy 的地址。
    •第三步便是访问页面同时监听结果,这里我们需要调用 new_har 方法,同时指定捕获 Resopnse Body 和 Headers 信息,紧接着调用 Selenium 的 get 方法访问一个页面,这时候浏览器便会加载这个页面,同时所有的请求和响应信息都会被记录到 HAR 中。
    •第四步便是读取 HAR 到内容了,我们调用 log 到 entries 字段,里面便包含了请求和响应的具体结果,这样所有的请求和响应信息我们便能获取到了,Ajax 的内容也不在话下。

    有了这个我们就不需要非得等页面加载出来之后再根据页面渲染结果提取信息了,Ajax 请求直接拿原始数据,爽歪歪!

  • 相关阅读:
    Linux 命令查找文件中某个字段所存在的位置
    PHP in_array() 函数
    php一维数组如何追加到二维数组
    电脑切换窗口
    微擎前端逻辑判断的时弹框
    JDBC批量处理
    数据库事务
    处理BLOB
    JDBC自动生成主键值
    JDBC的元数据
  • 原文地址:https://www.cnblogs.com/loren880898/p/13307090.html
Copyright © 2020-2023  润新知