【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 
driver = webdriver.Chrome()
driver.get('https://www.google.com')
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'
<br># 新建一个监控助手
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\n')
 
time.sleep(5)
<br># 输出交互的信息
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缓存去了。

你可能感兴趣的:(python,爬虫,开发语言)