zoukankan      html  css  js  c++  java
  • Python爬虫之获取请求头信息以及cookies信息.

    工作中与项目中需要取抓取一些股票的实时信息等,有两种取到可以获取到一些需要的数据,一种是花钱买一些接口服务,还有就是爬虫取网站爬取。

    本人略了解tcp/ip与http以及https协议,后两者作为建立在tcp/ip之上的应用层,在爬虫中最麻烦的可能就是cookies的获取,通过cookies信息,对方服务器就可以判断

    你是机器行为还是可能是人,简单的网站,可以直接从响应头获取到cookies,但如果是通过js设置的cookies或者其它取到设置的,那就很难获取到。

    如果cookies就算拿到了,最近在工作中还碰到在Post请求中,不仅带上了你的请求信息,还会通过一些算法携带一些认证信息,这个携带的认证信息,很有可能是通过cookie或者其它的一些参数计算出来的固定或者非固定的值。

    如果为固定值,只需要拿到该post请求头中的请求体信息就好了,如果为变动值,那只能通过破解js代码的逻辑,自己再算一套【现在还未碰到过如此变态的反爬】

    Python的爬虫中,我个人使用最多的应该是requests模块,作为封装在urllib包基础上的模块,确实用起来很爽。如果在requests中,带上需要的头信息,那对方服务器也就会欢迎你了。

    所以让selenium配合requests那用起来就嗨了。

    通过这里作者的转载:https://www.cnblogs.com/startnow/p/14635147.html

    可以发现三种方式,但我个人的总结,其实就是两种,一种是通过代理将selenium与服务器之间的所有交互拦截下来,然后分析其中的数据,

    还有一种本质是通过selenium内部的功能,拦截selenium内部的日志信息,然后通过查看日志,然后找出需要的请求信息。

    第一个是selenium-wire来实现,这是包的地址https://github.com/wkeeling/selenium-wire

    通过pip可以安装使用,这个软件本质也是在selenium与目标地址的交互中,设置了代理,通过代理,可以修改与获取网络传输中的任何信息。

    from seleniumwire import webdriver  # Import from seleniumwire
    
    # Create a new instance of the Chrome driver
    driver = webdriver.Chrome()
    
    # Go to the Google home page
    driver.get('https://www.google.com')
    
    # Access requests via the `requests` attribute
    for request in driver.requests:
        if request.response:
            print(
                request.url,
                request.response.status_code,
                request.response.headers['Content-Type']
            )
    

      这种方式还是比较方便的,你不用自己设置代理,不需要自己取处理繁杂的本地与服务器之间的交互信息,通过该模块提供的接口就可以实现功能的实现。

    第二种方式是通过自己假设代理服务器,来处理浏览器与服务器交互的信息

    代理的软件,我使用的是browsermob-proxy,地址在:https://github.com/lightbody/browsermob-proxy

    该软件通过Java编写,我不懂Java那就看如何用,下面展示的是我在mac上的使用配置。

    # 启动代理
    server = Server('browsermob-proxy-2.1-1.4/bin/browsermob-proxy')
    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)
    
    
    chrome_options = webdriver.ChromeOptions()
    
    chrome_options.add_argument('--ignore-certificate-errors')
    chrome_options.add_argument("--proxy-server={0}".format(proxy.proxy))
    
    browser = webdriver.Chrome(options=chrome_options)
    
    # 监听结果
    url2 = 'https://stockmarketmba.com/symbollookup.php'
    # url2 ='https://www.baidu.com'
    
    # 新建一个监控助手 proxy.new_har(options={ 'captureContent': True, 'captureHeaders': True }) time.sleep(2) browser.get(url2) time.sleep(3) browser.refresh() time.sleep(2) input_box = browser.find_element_by_xpath('//*[@id="search"]') input_box.send_keys('TSLA ') time.sleep(5)
    # 输出交互的信息 result = proxy.har print(str(proxy.har)) # 关闭代理和浏览器 proxy.close() browser.close()

    前面两种都是通过设置代理的方式获取网络的交互信息,在使用浏览器的时候会提示连接不安全,虽然我感觉没啥影响。

    第三种是通过selenium内置的性能测试模块的日志功能来实现读取selenium的浏览器与服务器的交互信息。

    from time import sleep
    
    from selenium import webdriver
    from selenium.webdriver import DesiredCapabilities
    
    # make chrome log requests
    capabilities = DesiredCapabilities.CHROME
    capabilities["loggingPrefs"] = {"performance": "ALL"}  # newer: goog:loggingPrefs
    driver = webdriver.Chrome(
        desired_capabilities=capabilities, executable_path="./chromedriver"
    )
    
    # fetch a site that does xhr requests
    driver.get("https://sitewithajaxorsomething.com")
    sleep(5)  # wait for the requests to take place
    
    # extract requests from logs
    logs_raw = driver.get_log("performance")
    logs = [json.loads(lr["message"])["message"] for lr in logs_raw]
    
    def log_filter(log_):
        return (
            # is an actual response
            log_["method"] == "Network.responseReceived"
            # and json
            and "json" in log_["params"]["response"]["mimeType"]
        )
    
    for log in filter(log_filter, logs):
        request_id = log["params"]["requestId"]
        resp_url = log["params"]["response"]["url"]
        print(f"Caught {resp_url}")
        print(driver.execute_cdp_cmd("Network.getResponseBody", {"requestId": request_id}))
    

      

    如果chrome版本大于75,需要进行一些修改设置

    答案的来源:https://stackoverflow.com/questions/56507652/selenium-chrome-cant-see-browser-logs-invalidargumentexception

    方案1:

    from selenium import webdriver
    from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
    from selenium.webdriver.chrome.options import Options
    
    d = DesiredCapabilities.CHROME
    d['loggingPrefs'] = { 'performance':'ALL' }
    
    chrome_options = Options()
    chrome_options.add_experimental_option('w3c', False)
    
    driver = webdriver.Chrome(desired_capabilities=d, options=chrome_options)
    

      

    方案2:

    import time
    
    from selenium import webdriver
    
    from selenium.webdriver import DesiredCapabilities
    
    capabilities = DesiredCapabilities.CHROME
    capabilities['goog:loggingPrefs'] = {"performance": "ALL"}  # newer: goog:loggingPrefs
    
    browser = webdriver.Chrome(desired_capabilities=capabilities)
    browser.get('https://www.baidu.com')
    time.sleep(2)
    
    
    
    logs_raw = browser.get_log("performance")
    print(type(logs_raw))
    browser.close()
    

      

    这样,三种方式以及模板,我都贴了,供自己与他们使用参考,虽然我现在没写后端,但希望大家写爬虫的时候,尽量少用或者不用多线程。

    不要给对象服务器太大的压力,Over

      

    Over不了了,在服务器上面部署selenium必须添加参数headless参数,但一旦添加了headless参数,chrome的头部信息中,可以从请求头中看到headless的信息

    为了避免被对方服务器发现,这种明显机器行为的头部信息,需要手动添加一个假的头部信息

    比如

    chrome_options.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:82.0)')
    

      

    经过本人测试,在headless的情况下,获取cookie可能失败,可以在需要cookie的页面多refresh几次,好了,今天就写到这里,我取写完整的脚本,将头信息部署到redis缓存去了。

  • 相关阅读:
    多线程
    JavaSE
    SpringBoot是什么,可以做什么?
    SSM框架中如何简便上传文件表单
    SQL语句全解,非常棒!
    关于HttpSession 和 Hibernate框架中 session异同点的简单解析
    关于Javascript中页面动态钟表的简单实现
    Java 面向对象 知识点基础浅谈
    Eclipse无法正常启动,弹出对话框内容为 A Java Runtime...
    关于Java中面向对象章节、IO 流中的重点基础知识。
  • 原文地址:https://www.cnblogs.com/sidianok/p/15048627.html
Copyright © 2011-2022 走看看