啓動:jupyter notebook 介紹: anaconda是一個集成環境(數據分析+機器學習) 提供了一個叫作jupyter的可視化工具(基於瀏覽器) jupyter的基本使用 快捷鍵: 插入cell:a,b 刪除:x 執行:shift+enter 切換cell的模式:y,m tab:自動補全 打開幫助文檔:shift+tab
風險所在php
如何規避風險css
爬蟲機制 :應用在網站中html
反反爬機制 : 應用在爬蟲程序中python
第一個反爬機制 :web
robots協議:純文本的協議面試
通用頭域包含請求和響應消息都支持的頭域。ajax
Request URL:請求的URL地址 Request Method: 請求方法,get/post/put/…… Status Code:狀態碼,200 爲請求成功 Remote Address:路由地址
1) Accept: 告訴WEB服務器本身接受什麼介質類型,*/* 表示任何類型,type/* 表示該類型下的全部子類型; 2)Accept-Charset: 瀏覽器申明本身接收的字符集 Accept-Encoding:瀏覽器申明本身接收的編碼方法,一般指定壓縮方法,是否支持壓縮,支持什麼壓縮方法(gzip, deflate) 3)Accept-Language: 瀏覽器申明本身接收的語言。語言跟字符集的區別:中文是語言,中文有多種字符集,好比big5,gb2312,gbk等等。 4)Authorization: 當客戶端接收到來自WEB服務器的 WWW-Authenticate 響應時,該頭部來回應本身的身份驗證信息給WEB服務器。 5)Connection:表示是否須要持久鏈接。close(告訴WEB服務器或者代理服務器,在完成本次請求的響應後,斷開鏈接, 不要等待本次鏈接的後續請求了)。keep-alive(告訴WEB服務器或者代理服務器,在完成本次請求的響應後,保持鏈接,等待本次鏈接的後續請求)。 6)Referer:發送請求頁面URL。瀏覽器向 WEB 服務器代表本身是從哪一個 網頁/URL 得到/點擊 當前請求中的網址/URL。 7)User-Agent: 瀏覽器代表本身的身份(是哪一種瀏覽器)。 8)Host: 發送請求頁面所在域。 9)Cache-Control:瀏覽器應遵循的緩存機制。 no-cache(不要緩存的實體,要求如今從WEB服務器去取) max-age:(只接受 Age 值小於 max-age 值,而且沒有過時的對象) max-stale:(能夠接受過去的對象,可是過時時間必須小於 max-stale 值) min-fresh:(接受其新鮮生命期大於其當前 Age 跟 min-fresh 值之和的緩存對象) 10)Pramga:主要使用 Pramga: no-cache,至關於 Cache-Control: no-cache。 11)Range:瀏覽器(好比 Flashget 多線程下載時)告訴 WEB 服務器本身想取對象的哪部分。 12)Form:一種請求頭標,給定控制用戶代理的人工用戶的電子郵件地址。 13)Cookie:這是最重要的請求頭信息之一
1)Age:當代理服務器用本身緩存的實體去響應請求時,用該頭部代表該實體從產生到如今通過多長時間了。 2)Accept-Ranges:WEB服務器代表本身是否接受獲取其某個實體的一部分(好比文件的一部分)的請求。bytes:表示接受,none:表示不接受。 3) Cache-Control:服務器應遵循的緩存機制。 public(能夠用 Cached 內容迴應任何用戶) private(只能用緩存內容迴應先前請求該內容的那個用戶) no-cache(能夠緩存,可是隻有在跟WEB服務器驗證了其有效後,才能返回給客戶端) max-age:(本響應包含的對象的過時時間) ALL: no-store(不容許緩存) 4) Connection: 是否須要持久鏈接 close(鏈接已經關閉)。 keepalive(鏈接保持着,在等待本次鏈接的後續請求)。 Keep-Alive:若是瀏覽器請求保持鏈接,則該頭部代表但願 WEB 服務器保持鏈接多長時間(秒)。例如:Keep- Alive:300 5)Content-Encoding:WEB服務器代表本身使用了什麼壓縮方法(gzip,deflate)壓縮響應中的對象。 例如:Content-Encoding:gzip 6)Content-Language:WEB 服務器告訴瀏覽器本身響應的對象的語言。 7)Content-Length:WEB 服務器告訴瀏覽器本身響應的對象的長度。例如:Content-Length: 26012 8)Content-Range:WEB 服務器代表該響應包含的部分對象爲整個對象的哪一個部分。例如:Content-Range: bytes 21010-47021/47022 9)Content-Type:WEB 服務器告訴瀏覽器本身響應的對象的類型。例如:Content-Type:application/xml 10)Expired:WEB服務器代表該實體將在何時過時,對於過時了的對象,只有在跟WEB服務器驗證了其有效性後,才能用來響應客戶請求。 11) Last-Modified:WEB 服務器認爲對象的最後修改時間,好比文件的最後修改時間,動態頁面的最後產生時間等等。 12) Location:WEB 服務器告訴瀏覽器,試圖訪問的對象已經被移到別的位置了,到該頭部指定的位置去取。 13)Proxy-Authenticate: 代理服務器響應瀏覽器,要求其提供代理身份驗證信息。 14)Server: WEB 服務器代表本身是什麼軟件及版本等信息。 15)Refresh:表示瀏覽器應該在多少時間以後刷新文檔,以秒計。
對稱密鑰加密 非對稱密鑰加密 證書密鑰加密
基於網絡請求的python模塊json
做用 :模擬瀏覽器發送請求,實現爬蟲flask
環境安裝 : pip install requestapi
編碼流程 :
import requests #1.指定url url = 'https://www.sogou.com/' #2.請求發送:get返回的是一個響應對象 response = requests.get(url=url) #3.獲取響應數據:text返回的是字符串形式的響應數據 page_text = response.text #4.持久化存儲 with open('./sogou.html','w',encoding='utf-8') as fp: fp.write(page_text)
url = 'https://www.sogou.com/web' #請求參數的動態化 wd = input('enter a key word:') params = { 'query':wd } response = requests.get(url=url,params=params) page_text = response.text fileName = wd+'.html' with open(fileName,'w',encoding='utf-8') as fp: fp.write(page_text) print(fileName,'爬取成功!')
上述代碼問題:
#亂碼問題的解決 url = 'https://www.sogou.com/web' #請求參數的動態化 wd = input('enter a key word:') params = { 'query':wd } response = requests.get(url=url,params=params) #將響應數據的編碼格式手動進行指定 response.encoding = 'utf-8' page_text = response.text fileName = wd+'.html' with open(fileName,'w',encoding='utf-8') as fp: fp.write(page_text) print(fileName,'爬取成功!')
#UA假裝操做 url = 'https://www.sogou.com/web' #請求參數的動態化 wd = input('enter a key word:') params = { 'query':wd } #UA假裝 headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36' } response = requests.get(url=url,params=params,headers=headers) #將響應數據的編碼格式手動進行指定 response.encoding = 'utf-8' page_text = response.text fileName = wd+'.html' with open(fileName,'w',encoding='utf-8') as fp: fp.write(page_text) print(fileName,'爬取成功!')
爬取豆瓣電影中動態加載出的電影詳情數據 :
url = 'https://movie.douban.com/j/chart/top_list' #參數動態化 params = { 'type': '17', 'interval_id': '100:90', 'action': '', 'start': '0', 'limit': '200', } response = requests.get(url=url,params=params,headers=headers) #json()返回的是序列化好的對象 movie_list = response.json() for movie in movie_list: print(movie['title'],movie['score'])
總結:對一個陌生的網站進行數據爬取的時候,首先肯定的一點就是爬取的數據是否爲動態加載出來的 是:須要經過抓包工具捕獲到動態加載數據對應的數據包,從中提取出url和請求參數。 不是:直接對瀏覽器地址欄的url發起請求便可 如何檢測爬取的數據是否是動態加載出來的? 經過抓包工具進行局部搜索就能夠驗證數據是否爲動態加載 搜索到:不是動態加載 搜索不到:是動態加載 如何定位動態加載的數據在哪呢? 經過抓包工具進行全局搜索進行定位
http://www.kfc.com.cn/kfccda/storelist/index.aspx
url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword' data = { 'cname': '', 'pid': '', 'keyword': '上海', 'pageIndex': '1', 'pageSize': '10', } address_dic = requests.post(url=url,data=data,headers=headers).json() for dic in address_dic['Table1']: print(dic['addressDetail'])
- 需求 https://www.fjggfw.gov.cn/Website/JYXXNew.aspx 福建省公共資源交易中心 提取內容: 工程建設中的中標結果信息/中標候選人信息 1. 完整的html中標信息 2. 第一中標候選人 3. 中標金額 4. 中標時間 5. 其它參與投標的公司
- 實現思路 - 確認爬取的數據都是動態加載出來的 - 在首頁中捕獲到ajax請求對應的數據包,從該數據包中提取出請求的url和請求參數 - 對提取到的url進行請求發送,獲取響應數據(json) - 從json串中提取到每個公告對應的id值 - 將id值和中標信息對應的url進行整合,進行請求發送捕獲到每個公告對應的中標信息數據
post_url = 'https://www.fjggfw.gov.cn/Website/AjaxHandler/BuilderHandler.ashx' headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36', 'Cookie': '_qddac=4-3-1.4euvh3.x4wulp.k1hj8mnw; ASP.NET_SessionId=o4xkycpib3ry5rzkvfcamxzk; Hm_lvt_94bfa5b89a33cebfead2f88d38657023=1570520304; __root_domain_v=.fjggfw.gov.cn; _qddaz=QD.89mfu7.7kgq8w.k1hj8mhg; _qdda=4-1.4euvh3; _qddab=4-x4wulp.k1hj8mnw; _qddamta_2852155767=4-0; _qddagsx_02095bad0b=2882f90558bd014d97adf2d81c54875229141367446ccfed2b0c8913707c606ccf30ec99a338fed545821a5ff0476fd6332b8721c380e9dfb75dcc00600350b31d85d17d284bb5d6713a887ee73fa35c32b7350c9909379a8d9f728ac0c902e470cb5894c901c4176ada8a81e2ae1a7348ae5da6ff97dfb43a23c6c46ec8ec10; Hm_lpvt_94bfa5b89a33cebfead2f88d38657023=1570520973' } data = { 'OPtype': 'GetListNew', 'pageNo': '1', 'pageSize': '10', 'proArea': '-1', 'category': 'GCJS', 'announcementType': '-1', 'ProType': '-1', 'xmlx': '-1', 'projectName': '', 'TopTime': '2019-07-10 00:00:00', 'EndTime': '2019-10-08 23:59:59', 'rrr': '0.7293828344656237', } post_data = requests.post(url=post_url,headers=headers,data=data).json() for dic in post_data['data']: _id = int(dic['M_ID']) detail_url = 'https://www.fjggfw.gov.cn/Website/AjaxHandler/BuilderHandler.ashx?OPtype=GetGGInfoPC&ID={}&GGTYPE=5&url=AjaxHandler%2FBuilderHandler.ashx'.format(_id) company_data = requests.get(url=detail_url,headers=headers).json()['data'] company_str = ''.join(company_data) print(company_str)
- 基於requests| - 基於urllib - 區別:urllib中的urlretrieve不能夠進行UA假裝
import requests headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36' }
#基於requests的圖片爬取 url = 'http://tva1.sinaimg.cn/mw600/007QUzsKgy1g7qzr59hk7j30cs0gxn82.jpg' img_data = requests.get(url=url,headers=headers).content #content返回的是byte類型的響應數據 with open('./123.jpg','wb') as fp: fp.write(img_data)
#基於urllib的圖片爬取 from urllib import request url = 'http://tva1.sinaimg.cn/mw600/007QUzsKgy1g7qzr59hk7j30cs0gxn82.jpg' request.urlretrieve(url,'./456.jpg')
概念:將一整張頁面中的局部數據進行提取/解析
做用:用來實現聚焦爬蟲的吧
實現方式:
數據解析的通用原理是什麼?
頁面中的相關的字符串的數據都存儲在哪裏呢?
- 基於聚焦爬蟲的編碼流程 - 指定url - 發起請求 - 獲取響應數據 - 數據解析 - 持久化存儲
- 將煎蛋網中的圖片數據進行爬取且存儲在本地 :
import re import os dirName = './imgLibs' if not os.path.exists(dirName): os.mkdir(dirName) url = 'http://jandan.net/pic/MjAxOTEwMDktNjY=#comments' page_text = requests.get(url,headers=headers).text #解析數據:img標籤的src的屬性值 ex = '<div class="text">.*?<img src="(.*?)" referrerPolicy.*?</div>' img_src_list = re.findall(ex,page_text,re.S) for src in img_src_list: if 'org_src' in src: src = re.findall('org_src="(.*?)" onload',src)[0] src = 'http:'+src imgName = src.split('/')[-1] imgPath = dirName+'/'+imgName request.urlretrieve(src,imgPath) print(imgName,'下載成功!!!')
- 環境的安裝: - pip install bs4 - pip install lxml - bs4的解析原理: - 實例化一個BeautifulSoup的一個對象,把即將被解析的頁面源碼數據加載到該對象中 - 須要調用BeautifulSoup對象中的相關的方法和屬性進行標籤訂位和數據的提取 - BeautifulSoup的實例化 - BeautifulSoup(fp,'lxml'):將本地存儲的html文檔中的頁面源碼數據加載到該對象中 - BeautifulSoup(page_text,'lxml'):將從互聯網中請求道的頁面源碼數據加載到改對象中 - 標籤的定位 - soup.tagName:只能夠定位到第一個tagName標籤 - 屬性定位:soup.find('tagName',attrName='value'),只能夠定位到符合要求的第一個標籤 - findAll:返回值是一個列表。能夠定位到符合要求的全部標籤 - 選擇器定位:soup.select('選擇器') - 選擇器:id,class,tag,層級選擇器(大於號表示一個層級,空格表示多個層級) - 取文本 - text:將標籤中全部的文本取出 - string:將標籤中直系的文本取出 - 取屬性 - tag['attrName']
from bs4 import BeautifulSoup fp = open('./test.html',encoding='utf-8') soup = BeautifulSoup(fp,'lxml') # soup.div # soup.find('div',class_='song') # soup.findAll('div',class_='song') # soup.select('#feng')[0] # soup.select('.tang > ul > li > a') # soup.select('.tang a') # tag = soup.b # tag.string # div_tag = soup.find('div',class_='tang') # div_tag.text a_tag = soup.select('#feng')[0] a_tag
- 使用bs4解析三國演義小說的標題和內容,存儲到本地 :
main_url = 'http://www.shicimingju.com/book/sanguoyanyi.html' page_text = requests.get(url=main_url,headers=headers).text #數據解析:章節的標題和詳情頁的url soup = BeautifulSoup(page_text,'lxml') a_list = soup.select('.book-mulu > ul > li > a') fp = open('./sanguo.txt','w',encoding='utf-8') for a in a_list: title = a.string detail_url = 'http://www.shicimingju.com'+a['href'] detail_page_text = requests.get(url=detail_url,headers=headers).text #數據解析:章節內容 detail_soup = BeautifulSoup(detail_page_text,'lxml') div_tag = detail_soup.find('div',class_='chapter_content') content = div_tag.text fp.write(title+':'+content+'\n') print(title,'寫入成功!!!') fp.close()
- 環境的安裝 - pip install lxml - 解析原理 - 實例化一個etree的對象,且把即將被解析的頁面源碼數據加載到該對象中 - 調用etree對象中的xpath方法結合這不一樣形式的xpath表達式進行標籤訂位和數據提取 - etree對象的實例化 - etree.parse('fileName') - 本地文檔 - etree.HTML(page_text) - 網絡請求 - 標籤訂位 - 最左側的/:必定要從根標籤開始進行標籤訂位 - 非最左側的/:表示一個層級 - 最左側的//:能夠從任意位置進行指定標籤的定位 - 非最左側的//:表示多個層級 - 屬性定位://tagName[@attrName="value"] - 索引定位://tagName[@attrName="value"]/li[2],索引是從1開始 - 邏輯運算: - 找到href屬性值爲空且class屬性值爲du的a標籤 - //a[@href="" and @class="du"] - 模糊匹配: - //div[contains(@class, "ng")] - //div[starts-with(@class, "ta")] - 取文本 - /text():直系的文本內容 - //text():全部的文本內容 - 取屬性 - /@attrName
from lxml import etree tree = etree.parse('./test.html') # tree.xpath('/html//title') # tree.xpath('//div') # tree.xpath('//div[@class="tang"]') # tree.xpath('//div[@class="tang"]/ul/li[2]') # tree.xpath('//p[1]/text()') # tree.xpath('//div[@class="song"]//text()') tree.xpath('//img/@src')[0]
url = 'https://www.huya.com/g/xingxiu' page_text = requests.get(url=url,headers=headers).text #數據解析 tree = etree.HTML(page_text) li_list = tree.xpath('//div[@class="box-bd"]/ul/li') for li in li_list: #實現的是頁面局部數據的指定數據的解析 title = li.xpath('./a[2]/text()')[0] author = li.xpath('./span/span[1]/i/text()')[0] hot = li.xpath('./span/span[2]/i[2]/text()')[0] print(title,author,hot)
# url = 'http://pic.netbian.com/4kmeinv/' #第一頁 #指定一個通用的url模板:不可變的 url = 'http://pic.netbian.com/4kmeinv/index_%d.html' dirName = './MZLib' if not os.path.exists(dirName): os.mkdir(dirName) for page in range(1,6): if page == 1: new_url = 'http://pic.netbian.com/4kmeinv/' else: new_url = format(url%page) page_text = requests.get(url=new_url,headers=headers).text #數據解析:圖片地址&圖片名稱 tree = etree.HTML(page_text) li_list = tree.xpath('//div[@class="slist"]/ul/li') for li in li_list: img_name = li.xpath('./a/img/@alt')[0] img_name = img_name.encode('iso-8859-1').decode('gbk')+'.jpg' img_src = 'http://pic.netbian.com'+li.xpath('./a/img/@src')[0] img_data = requests.get(img_src,headers=headers).content #圖片的二進制類型數據 img_path = dirName+'/'+img_name with open(img_path,'wb') as fp: fp.write(img_data) print('第{}頁爬取完畢!!!'.format(page))
url = 'https://www.aqistudy.cn/historydata/' page_text = requests.get(url,headers=headers).text tree = etree.HTML(page_text) # hot_cities = tree.xpath('//div[@class="bottom"]/ul/li/a/text()') # all_cities = tree.xpath('//div[@class="bottom"]/ul/div[2]/li/a/text()') tree.xpath('//div[@class="bottom"]/ul/div[2]/li/a/text() | //div[@class="bottom"]/ul/li/a/text()')
代理指的就是代理服務器 代理的做用 : 請求和響應數據的轉發 代理和爬蟲之間的關聯 : 能夠基於代理實現更換爬蟲程序請求的ip地址 代理網站 : 1. 西祠 https://www.xicidaili.com/nn/ 2. 快代理 3. www.goubanjia.comm 4. 代理精靈 http://http.zhiliandaili.cn/ 代理的匿名度 : 高匿 : 所訪問的服務器察覺不到是不是代理訪問,也沒法知曉真正訪問的ip 匿名 : 所訪問的服務器知道是代理訪問,但沒法查到真正的ip 透明 : 知道是代理,而且知道真實ip 類型 : http https
# 使用代理髮請求 import requests headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36', 'Connection':'close' } url = 'https://www.baidu.com/s?ie=UTF-8&wd=ip' page_text = requests.get(url,headers=headers,proxies={'https':'125.87.99.237:22007'}).text with open('./ip.html','w',encoding='utf-8') as fp: fp.write(page_text)
#構建一個付費的代理池 import random ips_pool = [] url = 'http://ip.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&groupid=0&qty=103&time=1&pro=&city=&port=1&format=html&ss=5&css=&dt=1&specialTxt=3&specialJson=&usertype=2' page_text = requests.get(url,headers=headers).text tree = etree.HTML(page_text) ip_list = tree.xpath('//body//text()') for ip in ip_list: dic = {'https':ip} ips_pool.append(dic) from lxml import etree url = 'https://www.xicidaili.com/nn/%d' #通用的url模板(不可變) all_ips = [] for page in range(1,5): new_url = format(url%page) page_text = requests.get(new_url,headers=headers,proxies=random.choice(ips_pool)).text tree = etree.HTML(page_text) #在xpath表達式中不能夠出現tbody標籤 tr_list = tree.xpath('//*[@id="ip_list"]//tr')[1:] for tr in tr_list: ip = tr.xpath('./td[2]/text()')[0] port = tr.xpath('./td[3]/text()')[0] type_ip = tr.xpath('./td[6]/text()')[0] dic = { 'ip':ip, 'port':port, 'type':type_ip } all_ips.append(dic) print(len(all_ips))
需求:將https://xueqiu.com/中的新聞數據進行爬取 爬蟲中處理cookie的操做 手動處理:將cookie寫在headers中 自動處理:session對象。 獲取session對象:requests.Session() 做用: session對象和requests對象均可以對指定的url進行請求發送。只不過使用session進行請求發送的過程當中若是產生了cookie則cookie會被自動存儲在session對象中
url = 'https://xueqiu.com/v4/statuses/public_timeline_by_category.json?since_id=-1&max_id=20352188&count=15&category=-1' news_json = requests.get(url,headers=headers).json() news_json #基於cookie操做的修正 session = requests.Session() url = 'https://xueqiu.com/v4/statuses/public_timeline_by_category.json?since_id=-1&max_id=20352188&count=15&category=-1' #將cookie存儲到session中,目的是將cookie獲取存儲到session中 session.get('https://xueqiu.com/',headers=headers) #保證該次請求時攜帶對應的cookie才能夠請求成功 news_json = session.get(url,headers=headers).json() news_json
使用線上的打碼平臺進行自動的識別: - 雲打碼 - 超級鷹 : - 註冊《用戶中心》身份的帳戶 - 登錄 - 建立一個軟件 - 下載示例代碼《開發文檔》
import requests from hashlib import md5 class Chaojiying_Client(object): def __init__(self, username, password, soft_id): self.username = username password = password.encode('utf8') self.password = md5(password).hexdigest() self.soft_id = soft_id self.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() chaojiying = Chaojiying_Client('bobo328410948', 'bobo328410948', '899370') #用戶中心>>軟件ID 生成一個替換 96001 im = open('a.jpg', 'rb').read() #本地圖片文件路徑 來替換 a.jpg 有時WIN系統需要// print(chaojiying.PostPic(im,1004)['pic_str']) #驗證碼識別函數的封裝 def transformCode(imgPath,imgType): chaojiying = Chaojiying_Client('bobo328410948', 'bobo328410948', '899370') im = open(imgPath, 'rb').read() return chaojiying.PostPic(im,imgType)['pic_str']
版本一 :
版本一的問題 :
請求須要有動態的參數
一般請狀況下動態變化的請求參數都會被隱藏在前臺頁面源碼中
from urllib import request #驗證碼的識別:將驗證碼下載到本地而後提交給打嗎平臺進行識別 main_url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx' page_text = requests.get(main_url,headers=headers).text tree = etree.HTML(page_text) code_src = 'https://so.gushiwen.org'+tree.xpath('//*[@id="imgCode"]/@src')[0] request.urlretrieve(code_src,'./code.jpg') #識別驗證碼 code_text = transformCode('./code.jpg',1004) login_url = 'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx' data = { '__VIEWSTATE': '8/BKAQBaZHn7+GP+Kl2Gx43fFO1NI32RMyVae0RyrtFQue3IAhzQKvkml41cIT42Y//OcQccA8AqGYkvB+NFkU43uaHqU69Y0Z1WT3ZRrr4vR+CF7JlBG29POXM=', '__VIEWSTATEGENERATOR': 'C93BE1AE', 'from': 'http://so.gushiwen.org/user/collect.aspx', 'email': 'www.zhangbowudi@qq.com', 'pwd': 'bobo328410948', 'code': code_text, 'denglu': '登陸', } print(code_text) page_text = requests.post(login_url,headers=headers,data=data).text with open('./login.html','w',encoding='utf-8') as fp: fp.write(page_text)
版本二 :
版本二遇到的問題 :
沒有攜帶cookie ,且這個網站的cookie在驗證碼的請求裏
#驗證碼的識別:將驗證碼下載到本地而後提交給打嗎平臺進行識別 main_url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx' page_text = requests.get(main_url,headers=headers).text tree = etree.HTML(page_text) code_src = 'https://so.gushiwen.org'+tree.xpath('//*[@id="imgCode"]/@src')[0] request.urlretrieve(code_src,'./code.jpg') #解析出動態變化的請求參數 __VIEWSTATE = tree.xpath('//*[@id="__VIEWSTATE"]/@value')[0] __VIEWSTATEGENERATOR = tree.xpath('//*[@id="__VIEWSTATEGENERATOR"]/@value')[0] #識別驗證碼 code_text = transformCode('./code.jpg',1004) 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': 'www.zhangbowudi@qq.com', 'pwd': 'bobo328410948', 'code': code_text, 'denglu': '登陸', } print(code_text) page_text = requests.post(login_url,headers=headers,data=data).text with open('./login.html','w',encoding='utf-8') as fp: fp.write(page_text)
版本三 (完美版):
s = requests.Session() #驗證碼的識別:將驗證碼下載到本地而後提交給打嗎平臺進行識別 main_url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx' page_text = s.get(main_url,headers=headers).text tree = etree.HTML(page_text) code_src = 'https://so.gushiwen.org'+tree.xpath('//*[@id="imgCode"]/@src')[0] # request.urlretrieve(code_src,'./code.jpg') code_data = s.get(code_src,headers=headers).content with open('./code.jpg','wb') as fp: fp.write(code_data) #解析出動態變化的請求參數 __VIEWSTATE = tree.xpath('//*[@id="__VIEWSTATE"]/@value')[0] __VIEWSTATEGENERATOR = tree.xpath('//*[@id="__VIEWSTATEGENERATOR"]/@value')[0] #識別驗證碼 code_text = transformCode('./code.jpg',1004) 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': 'www.zhangbowudi@qq.com', 'pwd': 'bobo328410948', 'code': code_text, 'denglu': '登陸', } print(code_text) page_text = s.post(login_url,headers=headers,data=data).text with open('./login.html','w',encoding='utf-8') as fp: fp.write(page_text)
- 反爬機制 - robots - UA檢測 - 圖片懶加載 - 代理 - cookie - 驗證碼 - 動態變化的請求參數 - 動態加載的數據
# 同步操做 import time start = time.time() def request(url): print('正在請求',url) time.sleep(2) print('請求完畢:',url) urls = [ 'www.1.com', 'www.b.com', 'www.3.com' ] for url in urls: request(url) print('總耗時:',time.time()-start)
# 異步操做 import time from multiprocessing.dummy import Pool start = time.time() pool = Pool(3) def request(url): print('正在請求',url) time.sleep(2) print('請求完畢:',url) urls = [ 'www.1.com', 'www.b.com', 'www.3.com' ] pool.map(request,urls) print('總耗時:',time.time()-start)
# 爬蟲+ 線程池 # server端 from flask import Flask,render_template from time import sleep app = Flask(__name__) @app.route('/bobo') def index_bobo(): sleep(2) return render_template('ip.html') @app.route('/jay') def index_jay(): sleep(2) return render_template('login.html') app.run() # 爬蟲 + 線程池 import time from multiprocessing.dummy import Pool import requests from lxml import etree start = time.time() urls = [ 'http://localhost:5000/jay', 'http://localhost:5000/bobo' ] def get_request(url): page_text = requests.get(url).text return page_text def parse(page_text): tree = etree.HTML(page_text) print(tree.xpath('//div[1]//text()')) pool = Pool(2) page_text_list = pool.map(get_request,urls) pool.map(parse,page_text_list) print(len(page_text_list)) print('總耗時:',time.time()-start)