我们再做爬虫或者自动化项目的时候,有时候是需要登陆网站进行爬取数据的,但要是每次运行程序后都登录一遍的话就会很麻烦,所以我们可以事先登录一遍,然后获取cookie保在本地,然后下次使用爬虫的时候直接读取保存的cookie就省去了登录的麻烦.
获取cookies
获取cookie 的方法很简单,一种是浏览器的cookie,还有一个是请求头headers中的cookie
def get_cookie():
browser = webdriver.Chrome()
browser.get('https://yuaneu.ro/login')
input('登录')
with open('cookies.txt', 'w') as cookief:
cookief.write(json.dumps(browser.get_cookies()))
headers_cookie = browser.execute_script('return document.cookie')
with open('headers_cookies.txt', 'w') as f:
f.write(headers_cookie)
print('cookies保存成功!')
当你在打开的网页登录完成后 在命令框里敲一下回车即会自动保存cookie
其中browser.get_cookies()
就是获取cookiebrowser.execute_script('return document.cookie')
是执行js语句document.cookie'
,但是注意 有些网站设置了HttpOnly的话可能无法通过js获取cookie
经过上述操作就会在当前目录下生成两个文件,接下来就是在爬虫中使用cookies
使用cookies
from fake_useragent import UserAgent
import requests
def spider():
ua = UserAgent()
with open('headers_cookies.txt', 'r')as f:
cookie = f.read()
headers = {
'cookie': cookie,
'User-Agent': ua.random
}
r = requests.get('https://yuaneu.ro',headers=headers)
def spider2():
browser.get('https://yuaneu.ro')
with open('cookies.txt', 'r') as cookief:
cookieslist = json.load(cookief)
for cookie in cookieslist:
browser.add_cookie(cookie)
browser.refresh()
因为cookies有很多条,所以用for循环将每条cookies都导入,然后刷新页面就是登录的状态了
使用远程调试接管已打开浏览器(更新)
在使用selenium时往往会因为一些网络原因或者程序bug导致程序异常退出,这个时候浏览器却不会退出,等下次重新运行程序时,又会从头开始打开浏览器执行,那有没有什么办法直接在之前的浏览器上执行呢?
所以我们可以使用remote-debugging
来接管已经运行的Chrome浏览器
- 首先我们需要执行命令启动支持远程调试功能的Chrome
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --remote-debugging-port=9222 --no-first-run --no-default-browser-check --user-data-dir=$(mktemp -d -t 'chrome-remote_data_dir')
开启一个远程端口为9222的远程调试端口
- 然后编写以下代码
from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
driver = webdriver.Chrome(options=chrome_options)
driver.get('https://www.baidu.com')
...
运行以后就可以在我们用命令打开的浏览器中打开百度网页,即使程序执行结束后浏览器也不会关闭,然后我们可以修改打开其他网站,也是会在刚刚我们操作的浏览器上执行的
只要不关闭最后一个浏览器标签,之后可以一直在这个浏览器里操作
(如果使用爬虫这样可以有效避免被检测webdriver,当然也可以添加--disable-blink-features=AutomationControlled
参数)
后记
你一定很好奇是否可以这样接管Firefox,很遗憾可能是不行的,我查了很多地方,都无果。
但是我在研究geckodriver的时候发现一个参数--connect-existing
Connect to an existing Firefox instance(连接到一个现有的Firefox实例)。
所以我尝试在启动geckodriver时加入这个参数和--marionette-port <PORT>
(使用上一个参数必须加的),但是它和selenium默认的--websocket-port
冲突,我又修改源码注释掉原来的参数,但是运行是报错了,进程返回码64,命令行使用错误。
最后还是没能成功接管Firefox。
Selenium如何接管已经运行的Chrome浏览器?