爲何要進行模擬登錄html
爲何須要識別驗證碼python
驗證碼識別:藉助於線上的一款打碼平臺(超級鷹,雲打碼,打碼兔)服務器
超級鷹的使用流程:http://www.chaojiying.com/about.htmlcookie
實現模擬登錄網絡
cookie操做:session
模擬登錄案例app
#模擬登錄爬取古詩文網站登錄界面 import requests from lxml import etree from chaojiying_Python.chaojiying import Chaojiying_Client #當你處理登錄爬蟲時要將請求換成session session = requests.Session() #將超級鷹下載的包封裝成一個函數進行引入調用 def get_codeImg_text(imgPath, imgType): chaojiying = Chaojiying_Client('超級鷹帳號', '超級鷹密碼', ' 899991') #用戶中心>>軟件ID 生成一個替換 96001 im = open(imgPath, 'rb').read() #本地圖片文件路徑 來替換 a.jpg 有時WIN系統需要// # print(chaojiying.PostPic(im, 1902)) return chaojiying.PostPic(im, imgType)['pic_str'] headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36" } #模擬登陸 #獲取驗證碼圖片 url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx' #解析驗證碼圖片 page_text = requests.get(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 = session.get(url=code_img_src,headers=headers).content with open('./code.jpg','wb') as fp: fp.write(code_img_data) #解析動態參數 __VIEWSTATE = tree.xpath('//input[@id="__VIEWSTATE"]/@value')[0] __VIEWSTATEGENERATOR = tree.xpath('//input[@id="__VIEWSTATEGENERATOR"]/@value')[0] print(__VIEWSTATE,__VIEWSTATEGENERATOR) #使用打碼平臺識別出來的驗證碼圖片數據 codeImg_text = get_codeImg_text('./code.jpg',1902) print(codeImg_text) login_url = 'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx' #動態參數:動態參數每每都會被隱藏在前臺頁面 data = { #處理了動態參數 "__VIEWSTATE": __VIEWSTATE, "__VIEWSTATEGENERATOR": __VIEWSTATEGENERATOR, "from": "http://so.gushiwen.org/user/collect.aspx", "email": "你的帳號", "pwd": "你的密碼", "code": codeImg_text, "denglu": "登陸", } #登錄發送post請求,且傳送data pages_text = session.post(url=login_url,headers=headers,data=data).text with open('./gushiwen.html','w',encoding='utf-8') as fp: fp.write(pages_text)
在爬取數據的時候可能會報出一個HttpConnectilonPool的錯誤dom
代理:異步
什麼是高匿名、匿名和透明代理?他們有什麼區別?jsp
類型:
簡單的ip代理演示
url = 'https://www.baidu.com/s?wd=ip' page_text = requests.get(url=url,headers=headers,proxies={'http':'177.91.254.51:9999'}) with open('./ip.html','w',encoding='utf-8') as fp fp.wirte(page_text)
線程池:儘量用在耗時較爲嚴重的操做中
視頻的請求下載
視頻的持久化存儲
使用模塊
#模塊引入 from multiprocessing.dummy import Pool #建立線程數量 pool = Pool(4) pool.map(func,iterable,chunksize=None) #map方法能夠基於異步實現:讓參數1對應的函數對參數2對應的容器元素一次進行操做,參數二必須是可迭代的,好比最典型的列表
模擬請求阻塞操做
普通的訪問方式 import time def my_request(url): print('正在請求:',url) #設置了休眠等待 time.sleep(10) print('請求完畢:', url) urls = [ 'www.1.com', 'www.2.com', 'www.3.com', 'www.4.com', ] start = time.time() for url in urls: my_request(url) print(time.time()-start)
使用線程池
#使用線程池 import time from multiprocessing.dummy import Pool pool = Pool(4) def my_request(url): print('正在請求:',url) time.sleep(10) print('請求完畢:', url) urls = [ 'www.1.com', 'www.2.com', 'www.3.com', 'www.4.com', ] start = time.time() pool.map(my_request,urls) print(time.time()-start) pool.close() #join的意思是讓主線程等待子線程所有結束後再結束 pool.join()
案例:對梨視頻的視頻爬取
#對梨視頻的視頻爬取 import re,random import requests from lxml import etree from multiprocessing.dummy import Pool pool = Pool(4) #定義一個函數,傳送每個url,下載視頻 def downloadDate(url): #content爬取二進制使用 return requests.get(url=url,headers=headers).content #定義一個函數,存儲每個視頻 def saveDate(data): name = str(random.randint(0,10000))+'mp4' with open(name,'wb') as fp: fp.write(data) print(name,'下載成功') url = 'https://www.pearvideo.com/category_1' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36" } page_text = requests.get(url=url,headers=headers).text tree = etree.HTML(page_text) li_list = tree.xpath('//ul[@id="listvideoListUl"]/li') #定義一個空列表存放全部的視頻連接 urls = [] for li in li_list: detail_url = 'https://www.pearvideo.com/'+li.xpath('./div/a/@href')[0] pages_text = requests.get(url=detail_url,headers=headers).text ex = 'srcUrl="(.*?)",vdoUrl' video_url = re.findall(ex,pages_text,re.S)[0] urls.append(video_url) #在耗時較爲嚴重的地方使用線程池,視頻的請求下載及持久化存儲 #讓函數對urls中的每個元素進行異步網絡請求下載 #函數不能傳參,不能加括號 #datas是一個列表,存儲的是全部的視頻二進制的數據 datas = pool.map(downloadDate,urls) pool.map(saveDate,datas) pool.close() #join的意思是讓主線程等待子線程所有結束後再結束 pool.join() #在獲取視頻連接的時候發現視頻並非存儲在標籤中,而是在js中的變量裏, # 此時咱們只能使用支持各類匹配的正則來獲取連接 """ var contId="1565375",liveStatusUrl="liveStatus.jsp", liveSta="",playSta="1",autoPlay=!1,isLiving=!1,isVrVideo=!1, hdflvUrl="",sdflvUrl="",hdUrl="",sdUrl="",ldUrl="", srcUrl="https://video.pearvideo.com/mp4/short/20190612/cont-1565375-14010027-hd.mp4", vdoUrl=srcUrl,skinRes="//www.pearvideo.com/domain/skin",videoCDN="//video.pearvideo.com"; """