此文转自:https://zhuanlan.zhihu.com/p/28587931 转录只是为了方便学习,感谢他的分享php
Python模拟登录让很多人伤透脑筋,今天奉上一种万能登录方法。你无须精通HTML,甚至也无须精通Python,但却能让你成功的进行模拟登录。本文讲的是登录全部网站的一种方法,并不局限于微博与知乎,仅用其做为例子来说解。html
用到的库有“selenium”和“requests”。经过selenium进行模拟登录,而后将Cookies传入requests,最终用requests进行网站的抓取。优势就是不但规避了“selenium”其自己抓取速度慢的问题(由于仅仅用其做为登录),又规避了利用requests登录时须要制做繁琐的Cookies的过程(由于是从selenium直接拿来cookies)。文章前面列出了步骤与代码,后面补充了登录微博与知乎的实例。python
文章最后给出了一个懒人的方法。想要走捷径的朋友直接看第四部知乎登录。该方法适用于登录全部网站,仅用知乎做为实例以方便讲解。web
------------开始---------chrome
须要材料:1.本身喜欢的webdriver (必须) 2.Anaconda(可选)。selenium是借助浏览器而运行的,所以须要额外下载一款小型浏览器。Anaconda推荐你们也去下载一个,它里面包含了众多python的库,用起来很方便,并且免费!友情连接:1.谷歌 Web Driver下载 2. Anaconda下载api
导入selenium库浏览器
from selenium import webdriver
明确模拟浏览器在电脑中存放的位置,好比我存在了D盘cookie
chromePath = r'D:\Python Program\chromedriver.exe'
用selenium的webdriver方程指明浏览器的路径,同时打开一个浏览器。模拟浏览器有多种可选,好比Firefox, Safari。本次用的是谷歌的模拟浏览器。注意:'.Chome'是大写字母。函数
wd = webdriver.Chrome(executable_path= chromePath)
让webdriver为你填写用户名和密码学习
wd.find_element_by_xpath('用户名选项卡位置').send_keys('用户名') wd.find_element_by_xpath('密码选项卡位置').send_keys('密码')
让webdrive点击登录,如果按钮就选择用click(),如果表单就选择submit()。
wd.find_element_by_xpath('登录按钮所在位置').click() #如果按钮
wd.find_element_by_xpath('登录按钮所在位置').submit() #如果表单
登录完成,全部的cookies如今都存在了'wd'里面,可随时调用。
导入requests库,并构建Session()
import reqeusts
req = requests.Session()
从‘wd'里调出cookies
cookies = wd.get_cookies()
将selenium形式的cookies转换为requests可用的cookies。
for cookie in cookies:
req.cookies.set(cookie['name'],cookie['value'])
大功告成!尝试用requests来抓取网页。
req.get('待测试的连接')
以上就是python模拟登录的万能方法,你无需分析传递给网站的Cookies。只须要告诉python在什么地方填写用户名与密码就能够。十分的便利。
import requests from selenium import webdriver chromePath = r'浏览器存放位置' wd = webdriver.Chrome(executable_path= chromePath) #构建浏览器 loginUrl = 'http://www.weibo.com/login.php' wd.get(loginUrl) #进入登录界面 wd.find_element_by_xpath('//*[@id="loginname"]').send_keys('userword') #输入用户名 wd.find_element_by_xpath('//*[@id="pl_login_form"]/div/div[3]/div[2]/div/input').send_keys('password') #输入密码 wd.find_element_by_xpath('//*[@id="pl_login_form"]/div/div[3]/div[6]/a').click() #点击登录 req = requests.Session() #构建Session cookies = wd.get_cookies() #导出cookie for cookie in cookies: req.cookies.set(cookie['name'],cookie['value']) #转换cookies test = req.get('待测试的连接')
解释下关键的几个步骤:
1.找位置。推荐使用谷歌浏览器来查找每一个元素的Xpath,参看这个:从Chrome获取XPATH路径。
2. 选择click函数仍是submit函数。推荐每一个都试一下,总会有一个成功的。
3.登录微博是被要求输入验证码怎么办?有时登录微博会被要求输入验证码,这个时候咱们能够加一行手动输入验证码的代码。例如:
wd.find_element_by_xpath('//*[@id="pl_login_form"]/div/div[3]/div[6]/a').click() #点击登录
wd.find_element_by_xpath('//*[@id="pl_login_form"]/div/div[3]/div[3]/div/input').send_keys(input("输入验证码: "))
wd.find_element_by_xpath('//*[@id="pl_login_form"]/div/div[3]/div[6]/a').click()#再次点击登录
输入验证码的时候须要点击两次登录。由于验证码的输入框只有在点击了一次登录后才会弹出来!根据每一个网站的不一样而灵活应用selenium是十分重要的!但这个和分析那些Cookies比起来简直是过小儿科了。
知乎常常更新,所以即便方法写好了也可能很差用。所以我想到了一个终极方法,半手动登录。仅用selenium打开一个浏览器,而后手动输入帐号密码,有验证码就填验证码。等到成功登录以后使用“get_cookies()”函数来调出它的Cookies。这个方法虽然看起来笨了点,可是效率比那些几百行的代码不知道要高多少!并且你还能够用手机扫描二维码登录!只要这些登录操做是在selenium所打开的浏览器内进行,selenium就能够彻底记录下这些Cookies。代码以下:
import time
import requests
from selenium import webdriver
chromePath = r'浏览器储存的位置'
wd = webdriver.Chrome(executable_path= chromePath)
time.sleep(45)#设定45秒睡眠,期间进行手动登录。十分关键,下面有解释。
cookies = wd.get_cookies()#调出Cookies
req = requests.Session()
for cookie in cookies:
req.cookies.set(cookie['name'],cookie['value'])
req.headers.clear()
test = req.get('待测试的连接')
req.headers.clear() 是删除原始req里面标记有python机器人的信息。这个信息会被一些网站(好比知乎)捕捉到。形成登录爬取失败。务必要删除!
time.sleep()能够暂停执行下面的程序。在此期间你能够进行手动登录,扫描二维码等。而后在45秒事后再让python执行后面的“cookies = wd.get_cookies()”。selenium的get.cookies方程能够抓取到你进行手动登录事后的cookies。时间值的设定根据本身须要的时间。若是你在程序中已经将网站名、用户名、密码、等所有输入就剩下一个验证码须要手动的话,仅设定几秒钟就能够了!加入time.sleep的好处就是程序自己是不须要中止执行的!下面的全部程序能够无缝衔接。
感谢你们读到这,文章最初说的懒人方法就是我登录知乎用到的这种方法,半手动。可是也不要以为它很差,毕竟咱们的目的是爬取网站的内容,尽快解决登录问题。开始爬取工做才是正确的方向。这个方法能够帮您迅速登录网站,节省大量时间。这个方法万能的原理就是它调用了真实的浏览器。那么只要在正常状况下浏览器可以访问的网站就均可以用这个方法登录。
-------------------------------------------
问题1:若是网站禁用selenium怎么办?
解决方案:这种状况极少。网站若是采用这种反爬虫手段的话很容易误伤真正的用户。若是真的遇到这种状况,只须要隐藏掉selenium中显示你是机器人的信息就能够了。参考连接:Can a website detect when you are using selenium with chromedriver?
问题2:如何让新打开的webdriver带有曾经保存过的cookies?
解决方案:将获取的cookies保存在本地。下次登录的时候直接导入本地的cookies。参考连接:How to save and load cookies using python selenium webdriver
from selenium import webdriver from requests import Session from time import sleep req = Session() req.headers.clear() chromePath = r'D:\Python Program\chromedriver.exe' wd = webdriver.Chrome(executable_path= chromePath) zhihuLogInUrl = 'https://www.zhihu.com/signin' wd.get(zhihuLogInUrl) wd.find_element_by_xpath('/html/body/div[1]/div/div[2]/div[2]/div[1]/div[1]/div[2]/span').click() wd.find_element_by_xpath('/html/body/div[1]/div/div[2]/div[2]/form/div[1]/div[1]/input').send_keys('username') wd.find_element_by_xpath('/html/body/div[1]/div/div[2]/div[2]/form/div[1]/div[2]/input').send_keys('password') sleep(10) #手动输入验证码 wd.find_element_by_xpath('/html/body/div[1]/div/div[2]/div[2]/form/div[2]/button').submit() sleep(10)#等待Cookies加载 cookies = wd.get_cookies() for cookie in cookies: req.cookies.set(cookie['name'],cookie['value'])