Selenium, 大名鼎鼎的Web自动化测试工具,可以跨越Linux、Windows、macOS等平台使用,支持Java、Python、C#、Ruby等多种语言编程,为Web系统自动化测试带来强大支持。通过WebDriver方便操作浏览器,这也给爬虫界带来十分的便利。它可以被称为爬虫登录的万能钥匙,可以横扫一切网站的登录。
如果说,完全用Python代码模拟登录是我们智力的体现,那么选择 Selenium 就是我们的智慧所在。没办法,用它就是一个字儿:倍儿爽!
1. Selenium 登录获取cookies的流程
利用这把万能钥匙的流程大致如下:
- 使用Selenium WebDriver 打开浏览器;
- 如果没有验证码,可以通过代码输入用户名和密码并点击登录按钮;如果需要人工输入变态的验证码,就让WebDriver sleep一定时间,等待人工输入完成;
- 登录后获取cookies,并保存到文件或数据库。
如果上述过程是不需要人工输入验证码的,可以使用 Headless Chrome ,它能在无桌面环境下运行,比如Linux 服务器上一般是没有安装桌面环境的。
获取cookies以后,我们可以继续用webdriver抓取数据页面,这适合于异步加载的页面的抓取;或者把cookies导入到requests的session,利用requests抓取数据页面,这适合于非异步加载的页面。
2. Selenium 登录的实现
按照上面的思路,我们实现两个登录的过程,一个需要验证码,一个不需要验证码。
不需要人工输入验证码的登录:
def login_auto(login_url, username, password, username_xpath, password_xpath, submit_xpath, cookies_file, browser=None): if browser is None: options = webdriver.ChromeOptions() # chrome在系统PATH时,可以不指定 binary_location # options.binary_location = ‘/usr/bin/google-chrome’ options.add_argument('headless') options.add_argument('window-size=1200x600') browser = webdriver.Chrome(chrome_options=options) browser.maximize_window() browser.get(login_url) time.sleep(9) # 等登录加载完成 browser.find_element_by_xpath(username_xpath).send_keys(username) browser.find_element_by_xpath(password_xpath).send_keys(password) browser.find_element_by_xpath(submit_xpath).send_keys(Keys.ENTER) time.sleep(9) # 等登录加载完成 cookies = browser.get_cookies() print(cookies) save_cookies(cookies, cookies_file)
这个login_auto()函数,使用了headless的chrome,最大化窗口的目的是让整个页面都显示出来,如果默认大小,微博登录页面就不显示登录输入框,自动填写用户名时会保存。
sleep的目的是等待加载登录页面完成,还是微博,它的登录跳转比较费时间,不能一下子加载完成,必须等待。
登录完成我们就可以得到cookies了。通过webdriver的get_cookies()得到的cookies是一个列表,每个元素是一个字典,包含了domain, expiry, name, value等等字段。
最后我们把得到的cookies保存为文件,这里用pickle直接序列化到硬盘,这个cookies就可以被爬虫使用抓取数据了。
需要人工输入验证码的登录
def login_manually(login_url, cookies_file, browser=None): # 既然是手动,这里就不自动填写用户名和密码了 if browser is None: browser = webdriver.Chrome() browser.get(login_url) time.sleep(30) # 给自己多了点时间输入用户名、密码、验证码 cookies = browser.get_cookies() print(cookies) save_cookies(cookies, cookies_file)
需要人工介入的登录,就是让程序自动打开一个浏览器,然后人工输入登录信息完成登录,最后程序保存cookies的过程。
这里可不能用headless的Chrome哦,不然你看不到浏览器窗口无法输入,哈哈哈~
当然,你也可以让程序自动填写用户名、密码,类似login_auto()那样实现,小猿们有兴趣的话可以添加这部分功能。
3. Selenium 登录后的cookies的使用
用Selenium保存的cookies,可以继续给WebDriver使用,去抓取复杂的异步加载(AJAX)的网页,也可以给requests使用快速加载非异步页面。为此,我们实现两个不同的加载函数:
加载cookies到WebDriver
def load_to_browser(cookies_file, browser=None): with open(cookies_file, 'rb') as f: cookies = pickle.load(f) if browser is None: browser = webdriver.Chrome() for cookie in cookies: browser.add_cookie(cookie) return browser
保存时用的是pickle序列化到硬盘,读取到内存时同样使用pickle, 把cookies放入WebDriver很简单,把cookies逐个用add_cookie()放入即可。
加载cookies到requests的session
requests的cookies是用RequestsCookieJar这个类管理的,它的结构和WebDriver 的cookies不太一样,它只需要name, value即可,所以加载到requests有些不同:
def load_to_requests(cookies_file, session=None): with open(cookies_file, 'rb') as f: cookies = pickle.load(f) if session is None: session = requests.Session() for cookie in cookies: session.cookies.set(cookie['name'], cookie['value'])
4. Selenium 登录实战: 微博、哔哩哔哩、知乎的登录
微博有时候是不需要输入验证码的,此时就可以自动化登录。幸运的是,我的账号在我机器上就不需要输入验证码,省的我费劲去找一个不需要验证码的网站(现如今真的很难找啊~) 好了,看代码:
login_url = 'https://weibo.com/' username_xpath = '//input[@id="loginname"]' password_xpath = '//input[@name="password"]' submit_xpath = '//a[@action-type="btn_submit"]' username = 'your-username' password = 'your-password' login_auto(login_url, username, password, username_xpath, password_xpath, submit_xpath, 'z-weibo.cookies') ``` 而哔哩哔哩、知乎都需要手动解锁验证码,那我们就用人工介入的模式登录: ```python login_url = 'https://passport.bilibili.com/login' login_manually(login_url, 'z-bilibili.cookies')
借用login_manually()函数是不是非常的简单,同样的知乎的也很简单:
login_url = 'https://passport.bilibili.com/login' login_manually(login_url, 'z-zhihu.cookies')
出乎意料的是,登录知乎出现了问题,报了一个错误:Missing argument grant_type。网上有人说是Chrome版本问题,降低版本后就可以了。
神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试