用爬虫实现验证码识别并模拟登陆和cookie操作、代理操作、线程池
一、模擬登陸
1、為什么要進行模擬登陸
有時,我們需要爬取一些基于個人用戶的用戶信息(需要登陸后才可以查看)
2、為什么要需要識別驗證碼
因為驗證碼往往是作為登陸請求中的請求參數被使用
3、驗證碼識別:借助于線上的一款打碼平臺(超級鷹、云打碼、打碼兔)
超級鷹網站:http://www.chaojiying.com/about.html
超級鷹的使用流程:
1、沒有就注冊一個有的話直接登陸
2、點擊 軟件ID? >? 生成一個軟件ID
3、下載實例代碼:點擊開發文檔? >? 選擇python語言 > 點擊下載
實例代碼展示
import requests from hashlib import md5 class Chaojiying_Client(object):def __init__(self, username, password, soft_id):self.username = usernamepassword = password.encode('utf8')self.password = md5(password).hexdigest()self.soft_id = soft_idself.base_params = {'user': self.username,'pass2': self.password,'softid': self.soft_id,}self.headers = {'Connection': 'Keep-Alive','User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',}def PostPic(self, im, codetype):""" im: 圖片字節codetype: 題目類型 參考 http://www.chaojiying.com/price.html""" params = {'codetype': codetype,}params.update(self.base_params)files = {'userfile': ('ccc.jpg', im)}r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)return r.json()def ReportError(self, im_id):""" im_id:報錯題目的圖片ID""" params = {'id': im_id,}params.update(self.base_params)r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)return r.json()if __name__ == '__main__':chaojiying = Chaojiying_Client('用戶名', '密碼', '軟件ID') #用戶中心>>軟件ID 生成一個替換 im = open('a.jpg', 'rb').read() #本地圖片文件路徑 來替換 a.jpg print(chaojiying.PostPic(im, 1902)) #1902 驗證碼類型 官方網站>>價格體系 3.4+版 print 后要加()?
下面用一個古詩詞的網站作為演示上下應該在一起但是太長了故分開寫了
先定義一個驗證碼識別的方法簡單的封裝下
def get_codeImg_text(imgPath,imgType):chaojiying = Chaojiying_Client('用戶名', '密碼', '軟甲ID') #用戶中心>>軟件ID 生成一個替換im = open(imgPath, 'rb').read()#本地圖片文件路徑 來替換 a.jpg return chaojiying.PostPic(im, imgType)['pic_str']編寫登陸爬蟲
import requests from lxml import etree#前期準備工作 session = requests.Session() headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.64 Safari/537.36", }#兩個url指向一樣只是方便區分所以寫了兩個 url = "https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx" login_url = 'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx'#請求登陸頁面并且將登陸頁面放到實例化的tree里 page_text = requests.session(url=url,headers=headers).text tree = etree.HTML(page_text)#解析驗證碼圖片保存到本地 code_img_src = 'https://so.gushiwen.org'+tree.xpath('//*[@id="imgCode"]/@src')[0] code_img_data = requests.session(url=code_img_src,headers=headers).content #直接獲取二進制流 with open("./code.jpg","wb") as f:f.write(code_img_data)#解析動態參數,動態參數往往都會隱藏在前臺頁面中 __VIEWSTATE = tree.xpath('//input[@id="__VIEWSTATE"]/@value')[0] __VIEWSTATEGENERATOR = tree.xpath('//input[@id="__VIEWSTATEGENERATOR"]/@value')[0]#使用打碼平臺識別出來的驗證碼圖片數據 codeImg_text = get_codeImg_text("./code.jpg",1902)#整合所需要的數據 data = {#處理了動態參數"__VIEWSTATE": __VIEWSTATE,"__VIEWSTATEGENERATOR": __VIEWSTATEGENERATOR,"from": "http://so.gushiwen.org/user/collect.aspx","email": "www.zhangbowudi@qq.com","pwd": "bobo328410948","code": codeImg_text,"denglu": "登錄", }#模擬登陸并把頁面寫入本地 page_text = requests.session(url=login_url,headers=headers,data=data).text with open("./login.html","w",encoding="utf-8") as f:f.write(page_text)?
關于前面的動態參數
所以我們要找到上面那兩個參數,不妨去前臺看看
放到圖片里的搜索框搜索下就可以了
因為這兩個也是作為參數發送到后端的所以不能少
因為用到了session所以該爬蟲的所有的請求均為session
?
二、代理操作
給大家直接推薦個網址:里面有詳細一些的描述在下就不在這里贅述了
因為是免費的所以成功率不大
http://www.goubanjia.com/
具體使用方法:
url = "https://www.baidu.com/s?ie=UTF-8&wd=ip" page_text = requests.get(url=url,headers=headers,proxies={"類型":"ip:端口號"}).textwith open("./ip.html",'w',encoding="utf-8") as f:f.write(page_text)?
三、線程池
線程池:盡可能用在耗時較為嚴重的操作中
使用模塊: #導包 from multiprocessing.dummy import Pool #實例化 pool = Pool(4)#線程數 pool.map(func,iterable,chunksize=None)可以基于異步實現:讓參數1(func)對應的函數對參數2(iterable)對應的容器元素依次進行操作(基于異步的操作)?
實例代碼,效率對比:
import time pool = Pool(4) def func(url):print("正在請求:",url)time.sleep(2)print("請求完畢:",url)urls = ["www.1.com","www.2.com","www.3.com","www.4.com", ] start = time.time() for url in urls:func(url) print(time.time()-start)start2 = time.time() pool.map(fun,urls) print(time.time()-start2)?
?
?
?
轉載于:https://www.cnblogs.com/guchenxu/p/11019860.html
總結
以上是生活随笔為你收集整理的用爬虫实现验证码识别并模拟登陆和cookie操作、代理操作、线程池的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UVa1601
- 下一篇: Python虚拟环境virtualenv