chrome浏览器窗口(高级版)
查看浏览器信息
在 chrome浏览器的地址栏中输入 chrome://version
到 chrome浏览器 安装的文件夹下,打开 cmd窗口,输入以下内容:
chrome.exe --remote-debugging-port=9527 --user-data-dir="C:\Users\21173\AppData\Local\Google\Chrome\User Data"
启动 chrome浏览器 的调试模式,
- user-data-dirr=“F:\selenium\AutomationProfile” 是在单独的配置文件中启动 chrome浏览器,可以是chrome安装目录下现有的用户数据文件,使用的话就可以跳过一些页面的登录状态;也可以理解为新的浏览器,创建对应文件夹;
- 其中 9527 为端口号,可自行指定
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_experimental_option("debuggerAddress", "127.0.0.1:9527")
browser = webdriver.Chrome(options=options)
url = 'https://www.bilibili.com'
browser.get(url)
print(browser.title)
option = webdriver.ChromeOptions()
option.add_argument('--headless')
option.add_argument("--user-data-dir=C:\\Users\\21173\\AppData\\Local\\Google\\Chrome\\User Data")
option.add_argument("--remote-debugging-port=9222")
option.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36")
driver = webdriver.Chrome(options=option)
driver.get(url)
执行cmd命令
使用os.popen即可执行cmd命令~(os.popen包装了sunprocess.Popen方法)
import os
os.popen('start chrome --remote-debugging-port=9527 --user-data-dir="F:\selenium"')
# 方法二
# 先切换到chrome的可执行文件路径,再执行cmd命令。注意这里没有 start
os.chdir(r"C:\Program Files\Google\Chrome\Application")
os.popen('chrome --remote-debugging-port=9527 --user-data-dir="F:\selenium"')
os.system
import os
# 方法一
os.system(r'start chrome --remote-debugging-port=9527 --user-data-dir="F:\selenium"')
# 方法二
# 先切换到chrome的可执行文件路径,再执行cmd命令。注意这里没有 start
os.chdir(r"C:\Program Files\Google\Chrome\Application")
os.system(r'chrome --remote-debugging-port=9527 --user-data-dir="F:\selenium"')
subprocess.Popen
import os
import subprocess
# 先切换到chrome可执行文件的路径
os.chdir(r"C:\Program Files\Google\Chrome\Application")
# 然后使用Popen执行cmd命令,这里的chrome.exe 可替换为 chrome,注意这里没有 start
subprocess.Popen('chrome.exe --remote-debugging-port=9527 --user-data-dir="F:\selenium"')
selenium操作chrome调试
from selenium import webdriver
if __name__ == '__main__':
browser = webdriver.Chrome()
browser.get('https://www.csdn.net/')
# 获取远程链接的地址
print('remote_url:', browser.caps['goog:chromeOptions']['debuggerAddress'])
print('session_id:', browser.session_id)
print(browser.title)
用调试模式执行以上代码,看到下图
{'debuggerAddress': 'localhost:64829'}
查看当前窗口的页面连接
点击 devtoolsFrontendUrl(开发工具前端Url)
,可以到调试界面,这个可以用作于远程调试
查看窗口远程链接
http://localhost:64829/json/version
- 圈出来的
webSocketDebuggerUrl(调试器Url)
,是远程链接的地址,若使用 puppeteer的话能用到
import os
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
if __name__ == '__main__':
os.system(r'start chrome --remote-debugging-port=9527 --user-data-dir="F:\selenium"')
# 完成登录扫码验证或者手机短信验证后,回车进入下一步
input('输入空格继续程序...')
options = Options()
options.add_experimental_option("debuggerAddress", "127.0.0.1:9527")
browser = webdriver.Chrome(options=options)
print(browser.title)
获取Network数据
通过selenium去拿网页数据,往往是两个途径:
- selenium.page_source,通过解析HTML
- 通过中间人进行数据截获
应用场景
Chrome浏览器-> 开发者工具 -> Network 中所有的数据包
Selenium3获取Network
这里指定9527端口打开浏览器,也可以不指定
Selenium4获取Network
在Selenium 4中,
desired_capabilities
已经被弃用,所以不能再在webdriver.Chrome()
中使用它。需要将desired_capabilities
转换为options
日志没有response.body
步骤:通过Chromedriver获取到network日志。network 的response日志类型Network.responseReceived,里面有个参数 requestId , chrome devtool Network.getResponseBody方法可以通过requestId 获取到response
{'level':'INFO','message':
{
"message":{
"method":"Network.responseReceived",
"params":{
"frameId":"35489C704F5D95B9D01BD99C00BA3AFA",
"loaderId":"BA3FE8EAD2BB30562343F3940AEB8CBC",
"requestId":"BA3FE8EAD2BB30562343F3940AEB8CBC",
"response":{
"connectionId":12,
"connectionReused":false,
"encodedDataLength":230,
"fromDiskCache":false,
"fromPrefetchCache":false,
"fromServiceWorker":false,
"headers":{
"Access-Control-Allow-Credentials":"true",
"Access-Control-Allow-Origin":"*",
"Connection":"keep-alive",
"Content-Length":"571",
"Content-Type":"application/json",
"Date":"Tue, 24 Nov 2020 01:59:03 GMT",
"Server":"gunicorn/19.9.0"
},
"headersText":"HTTP/1.1 200 OK,
Date: Tue, 24 Nov 2020 01:59:03 GMT
Content-Type: application/json
Content-Length: 571
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true",
"mimeType":"application/json",
"protocol":"http/1.1",
"remoteIPAddress":"3.211.1.78",
"remotePort":80,
"requestHeaders":{ "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Accept-Encoding":"gzip, deflate",
"Accept-Language":"en-US",
"Connection":"keep-alive",
"Host":"httpbin.org",
"Upgrade-Insecure-Requests":"1",
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:55.0) Gecko/20100101 Firefox/55.0"
},
"requestHeadersText":"GET /get HTTP/1.1
Host: httpbin.org
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:55.0) Gecko/20100101 Firefox/55.0
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US
",
"responseTime":1606183143651.414,
"securityState":"insecure",
"status":200,
"statusText":"OK",
"timing":{
"connectEnd":282.386,
"connectStart":47.972,
"dnsEnd":47.972,
"dnsStart":46.748,
"proxyEnd":-1,
"proxyStart":-1,
"pushEnd":0,
"pushStart":0,
"receiveHeadersEnd":519.16,
"requestTime":43961290.624483,
"sendEnd":282.616,
"sendStart":282.547,
"sslEnd":-1,
"sslStart":-1,
"workerFetchStart":-1,
"workerReady":-1,
"workerRespondWithSettled":-1,
"workerStart":-1
},
"url":"http://httpbin.org/get"
},
"timestamp":43961291.145069,
"type":"Document"
}
},
"webview":"35489C704F5D95B9D01BD99C00BA3AFA"
}}
过滤请求包,一般来说,像图片、css&js文件等,往往是不需要的,所以可以对它们过滤
最后是获取数据包的 requestId,好比每个网络数据包的身份证。
在Selenium中调用cdp时候,需要传入 requestId,浏览器会验证是否存在该 requestId,
如果存在,则响应并返回数据;
如果不存在,则会抛出 WebDriverException 异常
import json
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.chrome.options import Options
options = Options()
caps = {
"browserName": "chrome",
'goog:loggingPrefs': {'performance': 'ALL'} # 开启日志性能监听
}
# 将caps添加到options中
for key, value in caps.items():
options.set_capability(key, value)
# 启动浏览器
browser = webdriver.Chrome(options=options)
browser.get('https://www.baidu.com')
def filter_type(_type: str):
types = [
'application/javascript', 'application/x-javascript', 'text/css', 'webp', 'image/png', 'image/gif',
'image/jpeg', 'image/x-icon', 'application/octet-stream'
]
if _type not in types:
return True
return False
performance_log = browser.get_log('performance') # 获取名称为 performance 的日志
for packet in performance_log:
message = json.loads(packet.get('message')).get('message') # 获取message的数据
if message.get('method') != 'Network.responseReceived': # 如果method 不是 responseReceived 类型就不往下执行
continue
packet_type = message.get('params').get('response').get('mimeType') # 获取该请求返回的type
if not filter_type(_type=packet_type): # 过滤type
continue
requestId = message.get('params').get('requestId') # 唯一的请求标识符。相当于该请求的身份证
url = message.get('params').get('response').get('url') # 获取 该请求 url
try:
resp = browser.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId}) # selenium调用 cdp
print(f'type: {packet_type} url: {url}')
print(f'response: {resp}')
except WebDriverException: # 忽略异常
pass
注意事项:
- CDP主要关注HTTP和HTTPS请求,其它协议的可能无法捕获
- 页面加载过程中的限制或动态加载的内容,等待一段时间,等页面完全加载好,再获取 CDP 日志
- 资源策略和跨域限制
Python字符串前缀u、r、b、f含义
1、字符串前加 u
例子:
u”字符串中有中文”
含义:
前缀u表示该字符串是unicode编码,Python2中用,用在含有中文字符的字符串前,防止因为编码问题,导致中文出现乱码。另外一般要在文件开关标明编码方式采用utf8。Python3中,所有字符串默认都是unicode字符串。
2、字符串前加 r
例子:
r”\n\t”
含义:
在普通字符串中,反斜线是转义符,代表一些特殊的内容,如换行符\n。
前缀r表示该字符串是原始字符串,即\不是转义符,只是单纯的一个符号。
常用于特殊的字符如换行符、正则表达式、文件路径。
注意不能在原始字符串结尾输入反斜线,否则Python不知道这是一个字符还是换行符(字符串最后用\表示换行),会报错:
SyntaxError: EOL while scanning string literal
那如果是一个文件夹路径就是以\结尾怎么办呢,可以再接一个转义\的字符串:
>>>print r'C:\Program File\my\path''\\'
C:\Program File\my\path\
3、字符串前加 b
例子:
b'<h1>Hello World!</h1>'
含义:
前缀b表示该字符串是bytes类型。用在Python3中,Python3里默认的str是unicode类。Python2的str本身就是bytes类,所以可不用。
常用在如网络编程中,服务器和浏览器只认bytes类型数据。如:send 函数的参数和 recv 函数的返回值都是 bytes 类型。
在 Python3 中,bytes 和 str 的互相转换方式是
str.encode('utf-8')
bytes.decode('utf-8')
频繁更换ip
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
option = webdriver.ChromeOptions()
option.add_argument('--no-sandbox')
option.add_argument('--headless')
#设置user-agent
option.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:55.0) Gecko/20100101 Firefox/55.0')
caps = DesiredCapabilities.CHROME
driver = webdriver.Chrome(options=option,desired_capabilities=caps)
p = '222.185.28.38:32374'
proxy = Proxy(
{
'proxyType':ProxyType.MANUAL,
'httpProxy':'{}'.format(p),
}
)
proxy.add_to_capabilities(caps)
driver.start_session(caps)
driver.get('http://httpbin.org/get')
print(driver.page_source)
#更换proxy后 重新执行proxy.add_to_capabilities(caps) 和 driver.start_session(caps)即可。不用重启driver更新代理成功。
Selenium Webdriver常用方法
操作Element对象
find_element_by_id("user_name").clear() # 清楚元素内容
find_element_by_id("user_name").send_keys("username") # 按键输入
find_element_by_id("dl_an_submit").click() # 单机元素
find_element_by_id("dl_an_submit").submit() # 提交表单
- Element常用方法
driver.find_element_by_name('tj_trnews').size # 元素尺寸
driver.find_element_by_name('tj_trnews').text # 返回元素文本
driver.find_element_by_name('tj_trnews').get_attribute('class') # 获取属性值
driver.find_element_by_name('tj_trnews').is_displayed() # 是否用户可见
鼠标事件
from selenium.webdriver.common.action_chains import ActionChains
el = driver.find_element_by_name('tj_trnews') # 目标元素
ActionChains(driver).context_click(el).perform() # 右击目标元素
ActionChains(driver).double_click(el).perform() # 双击目标元素
source = driver.find_element_by_id('lg') # 目标元素原始位置
target = driver.find_element_by_id('kw') # 拖动的目标位置
ActionChains(driver).drag_and_drop(source, target).perform() # 拖动元素
ActionChains(driver).move_to_element(el).perform() # 鼠标移动的目标元素上
ActionChains(driver).click_and_hold(el).perform() # 移动到目标元素按下鼠标左键
键盘事件
from selenium.webdriver.common.keys import Keys
driver.get("https://www.baidu.com/")
driver.find_element_by_id("kw").send_keys("selenium") # 输入框输入内容
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE) # 从后删除一个字符(删除键)
driver.find_element_by_id("kw").send_keys(Keys.SPACE) # 输入空格
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a') # ctrl + a 全选输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x') # ctrl + x 剪切输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'v') # ctrl + v 粘贴
driver.find_element_by_id("su").send_keys(Keys.ENTER) # 回车
设置等待时间
- 强制等待sleep() 强制等待比较暴力,调用time模块的sleep()方法
- 隐性等待implicitly_wait()是设置了最大等待时间,如果在规定时间内加载完成,则继续执行下面操作,否则一直等到时间截止再执行下一步。如果需要的元素已经加载出来了,但是页面整体还没有加载完成,程序也会一直等待,也并不智能。
- 显性等待WebDriverWait() 需要传入一个判断条件的匿名函数,每隔一段时间去判断条件函数,如果条件成立则继续下一步,如果不成立则继续等待。
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import time
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
# 强制等待
time.sleep(5)
# 隐形等待
driver.implicitly_wait(30)
# 显性等待
element=WebDriverWait(driver, 10).until(lambda driver:driver.find_element_by_id("kw")) # 当找到id为kw的元素时才执行下一步。超时时间为10秒,默认每0.5秒检测一次。
定位frame中的对象
driver.switch_to.frame()
frame方法接收三种参数:frame name、index 和webelement
driver.switch_to.frame('frame_name')
driver.switch_to.frame(0) #第一个frame
driver.switch_to.default_content() #回到主体框架
driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0])
多窗口切换
要想在多个窗口之间切换,首先要获得每一个窗口的唯一标识符号(句柄)。通过获得的句柄来区别分不同的窗口,从而切换不同窗。
driver.get("http://example.com") # 打开一个窗口
now_handle = drvier.current_window_handle # 获取当前窗口句柄
driver.find_element_by_name('example').click() # 点击某个元素打开新的窗口(target="_black"的元素)
all_handle = drvier.window_handles # 获取所有窗口句柄
drvier.switch_to.window(now_handle) # 切换为第一窗口
driver.close() # 关闭当前窗口
下拉框处理
webdriver处理下拉框首先定位到下拉框内容,然后click某个option即可
m=driver.find_element_by_id("ShippingMethod") # 首先定位到下拉框
m.find_element_by_xpath("//option[@value='10.69']").click() # 然后点击下拉框选项
执行JavaScrapt
driver.execute_script('Java Scrapt Code')
# 例如下拉浏览器滚动条
driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
Cookie处理
webdriver可以对cookie进行读取、增加、删除
get_cookies() # 获得所有 cookie 信息
get_cookie(name) # 返回特定 name 有 cookie 信息
add_cookie(cookie_dict) # 添加 cookie,必须有 name 和 value 值
delete_cookie(name) # 删除特定(部分)的 cookie 信息
delete_all_cookies() # 删除所有 cookie 信息
处理弹出窗口和警告:使用Selenium的方法来处理网页中的弹出窗口和警告。
from requestium import Session
s = Session(webdriver_path='path/to/your/webdriver')
s.get('http://example.com')
# 点击会导致弹出窗口的按钮
s.driver.find_element_by_id('my-button').click()
# 接受弹出的确认对话框
alert = s.driver.switch_to.alert
alert.accept()
# 或者,如果要取消对话框
# alert.dismiss()
# 处理警告消息
s.get('http://example.com')
# 执行会导致警告的JavaScript代码
s.driver.execute_script("window.alert('Hello, World!');")
# 获取并接受警告
alert = s.driver.switch_to.alert
alert.accept()
截图和录像:使用Selenium的方法来截取网页的屏幕截图或录制视频。录制视频功能可能需要额外的库(如ffmpeg)和配置
from requestium import Session
import time
s = Session(webdriver_path='path/to/your/webdriver')
s.get('http://example.com')
# 截取屏幕截图并保存为图片文件
s.driver.get_screenshot_as_file('screenshot.png')
# 或者,获取截图的Base64编码
screenshot_base64 = s.driver.get_screenshot_as_base64()
# 录制网页操作的视频(需要安装额外的库如ffmpeg)
s.driver.start_recording_screen(video_name='recording.mp4')
# 进行一些操作...
time.sleep(5) # 操作持续5秒
s.driver.stop_recording_screen()
requestium模块
可以使用requestium模块,由于Requestium是基于Selenium和Requests的,使用前确保安装这两个库
from selenium import webdriver
from requestium import Session, Keys
firefox_driver = webdriver.Firefox()
s = Session(driver=firefox_driver)
不需要解析响应,当调用 xpath,css 或 re 时,它会自动完成
response = s.get('http://samplesite.com/sample_path')
cmnt_karma = response.xpath("//span[@class='karma comment-karma']//text()").extract_first()
# Extracts the first match
identifier = response.re_first(r'ID_\d\w\d', default='ID_1A1')
# Extracts all matches as a list
users = response.re(r'user_\d\d\d')
添加 Cookie
ensure_add_cookie 方法使得添加 Cookie 更加稳健。Selenium 需要浏览器在能够添加 Cookie 之前处于 Cookie 的域中。
此方法提供了几种解决方法。
- 如果浏览器不在 Cookie 域中,它会先获取域然后再添加 Cookie。
- 它还允许你在添加 Cookie 之前覆盖域,并避免执行此 GET。域可以被覆盖为 ‘ ’,这将把 Cookie 的域设置为驱动程序当前所在的任何域。
- 如果无法添加 cookie,它会尝试使用限制性较小的域(例如:home.site.com -> site.com)进行添加,然后在失败之前
cookie = {"domain": "www.site.com",
"secure": false,
"value": "sd2451dgd13",
"expiry": 1516824855.759154,
"path": "/",
"httpOnly": true,
"name": "sessionid"}
s.driver.ensure_add_cookie(cookie, override_domain='')
处理Cookies和Headers:使用Requests的方式设置和管理Cookies和Headers
from requestium import Session
s = Session(webdriver_path='path/to/your/webdriver')
# 设置请求头
headers = {'User-Agent': 'My User Agent'}
s.headers.update(headers)
# 发送带Header的GET请求
s.get('http://example.com', headers=headers)
# 获取并保存Cookies
cookies = s.cookies
# 在后续请求中使用已保存的Cookies
s.get('http://another-example.com', cookies=cookies)
等待元素
ensure_element_by_ 方法等待元素在浏览器中加载,并在加载后立即返回。它以 Selenium的 find_element_by_ 方法命名(如果找不到元素,它们会立即引发异常)
Requestium 可以等待一个元素处于以下任何状态:
- 存在(默认)
- 可点击,clickable
- 看得见的,visible
- 不可见(可用于等待加载… GIF 消失等)
这些方法对于单页面 Web 应用程序非常有用,其中站点动态地更改其元素。通常用 ensure_element_by_ 调用替换我们的 find_element_by_ 调用,因为它们更灵活。使用这些方法获取的元素具有新的 ensure_click 方法,这使得点击不太容易失败
s.driver.ensure_element_by_xpath(“//li[@class=’b1’]”, state=’clickable’, timeout=5).ensure_click()
state=’clickable’;
异步请求和多线程处理:虽然Requestium本身不直接支持异步请求或多线程处理,但你可以结合其他库(如asyncio或concurrent.futures)来实现这些功能。
import asyncio
from requestium import Session
async def fetch_page(session, url):
await asyncio.sleep(1)
session.driver.get(url)
return session.driver.page_source
async def main():
s = Session(webdriver_path='E:\python\chromedriver.exe')
tasks = []
urls = ['https://www.baidu.com', 'https://www.bilibili.com/', 'https://www.jd.com']
for url in urls:
tasks.append(fetch_page(s, url))
results = await asyncio.gather(*tasks)
s.driver.quit()
for result in results:
print(result)
asyncio.run(main())
问题:
- python异步协程爬虫报错:【TypeError: object int can‘t be used in ‘await‘ expression】
错误的原因可能是在async函数中使用了一个整数类型的变量作为await的参数。await只能用于返回协程对象的异步函数,无法使用在普通的同步操作上
解决这个问题,需要确保await的参数是一个异步函数的返回值。如果我们只是想等待一个时间段后再执行下一个操作,可以使用asyncio.sleep()函数作为协程对象来等待一定的时间
- OSError: [WinError 6] 句柄无效的解决办法
解决方案:
关闭driver 时 , 使用 driver.quit()代替 driver.close()
区别
close:只会关闭焦点所在的当前窗口
quit:会关闭所有关联的窗口
webdriver和requests相互切换
切换回使用 Requests:transfer_driver_cookies_to_session()
切换到使用 Selenium Webdriver 来运行:
transfer_session_cookies_to_driver()提升效率
import time,sys,os
from requestium import Session, Keys
s = Session(webdriver_path='/Users/lib/Documents/chromedriver',
browser='chrome',
default_timeout=15,
webdriver_options={'arguments': ['disable-gpu',"--user-agent=Mozilla/5.0 (iPod; U; CPU iPhone OS 2_1 like Mac OS X; ja-jp) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5F137 Safari/525.20"]})
#webdriver_options={'arguments': ['headless','--proxy-server=http://user:pwd@ip2.hahado.cn:40275']})
#webdriver_options={'arguments': ['headless','--proxy-server=http://116.11.254.37:80']})
#url = 'https://icanhazip.com/'
url = 'https://www.che300.com/pinggu/v9c9m30614r2016-06g2.8'
url = 'https://magi.com/search?q=%E6%96%B0%E5%86%A0'
url = 'http://m.baidu.com/s?word=%E6%88%BF%E5%B1%B1%E6%96%B0%E7%9B%98'
s.driver.get(url)
html = s.driver.page_source
print (html)
#pic = response.xpath('//img/@src').extract_first()
pic = None
#if pic is not None:
if u'访问太过于频繁,请输入验证码后再次访问' in html:
#print pic
code = raw_input('请输入验证码:')
print ('您输入的验证码是:%s' % code)
s.driver.find_element_by_xpath("//input[@name='code']").send_keys(code,Keys.ENTER)
time.sleep(1)
s.driver.ensure_element_by_xpath("//input[@type='submit']").click()
#self.s.transfer_driver_cookies_to_session()
#s.transfer_session_cookies_to_driver()
time.sleep(3)
print (s.driver.page_source)
s.driver.quit()
requestium实现自动登录获取网页cookie信息并爬取数据
(1)有些网站设置了反爬机制,我们需要手动添加headers,加入user-agent参数
from requestium import Session, Keys
import time
import json
import requests
#将cookie信息添加进requests组件中
def add_cookies(cookie,s):
u"往session添加cookies"
c = requests.cookies.RequestsCookieJar()
for i in cookie: #添加cookie到CookieJar
#print(i)
c.set(i["name"], i["value"])
s.cookies.update(c) #更新session里的cookie
return s
#获取cookie信息
def getCookie():
#webdriver驱动地址根据实际修改
s = Session(webdriver_path='D:/chromedriver_win32/chromedriver.exe',
browser='chrome',
default_timeout=15,
webdriver_options={'arguments': ['headless']})
s.driver.get('填写登录网址')
time.sleep(1)
s.driver.ensure_element_by_id('username').clear()
s.driver.ensure_element_by_id('username').send_keys('用户名')
s.driver.ensure_element_by_id('password').clear()
s.driver.ensure_element_by_id('password').send_keys('密码')
s.driver.ensure_element_by_id('login').click()
time.sleep(3)
url = s.driver.current_url
cookie = s.driver.get_cookies()
#print(cookie)
jsonCookies = json.dumps(cookie) #转字符串
s.driver.close()
return cookie
if __name__ == '__main__':
s = requests.session()
cookie = getCookie()
#为requests组件加入cookie信息
add_cookies(cookie,s)
#请求需要的数据
data = {
'response_data': json.dumps(response_data),
'filter_condition_key':'',
'_search': 'False',
'nd': 1576549859948,
'rows': 100,
'page': 1,
'sidx': '',
'sord': 'asc',
'Q^ALERT_TIME_START_^DL': 'xxx',
'Q^ALERT_TIME_START_^DG': 'xxx'
}
#反爬破解机制,加入自己网页的user-agent
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36 SLBrowser/6.0.1.4221'}
response = s.post('需要抓取数据的网址', headers,data=data)
if response.content:
print(response.json())