Python
爬蟲主要是爲了方便學習新語言和學習資料的爬取
robots.txt
是一個純文本文件,在這個文件中網站管理者能夠聲明該網站中不想被robots訪問的部分,或者指定搜索引擎只收錄指定的內容,通常域名後加/robots.txt
,就能夠獲取
當一個搜索機器人(有的叫搜索蜘蛛)訪問一個站點時,它會首先檢查該站點根目錄下是否存在robots.txt
,若是存在,搜索機器人就會按照該文件中的內容來肯定訪問的範圍;若是該文件不存在,那麼搜索機器人就沿着連接抓取
另外,robots.txt
必須放置在一個站點的根目錄下,並且文件名必須所有小寫。
robots.txt
寫做語法
首先,咱們來看一個robots.txt
範例:https://fanyi.youdao.com/robots.txt
訪問以上具體地址,咱們能夠看到robots.txt
的具體內容以下html
User-agent: Mediapartners-Google Disallow: User-agent: * Allow: /fufei Allow: /rengong Allow: /web2/index.html Allow: /about.html Allow: /fanyiapi Allow: /openapi Disallow: /app Disallow: /?
以上文本表達的意思是容許全部的搜索機器人訪問fanyi.youdao.com
站點下的全部文件
具體語法分析:User-agent
:後面爲搜索機器人的名稱,後面若是是*
,則泛指全部的搜索機器人;Disallow
:後面爲不容許訪問的文件目錄python
robots.txt
自身是一個文本文件。它必須位於域名的根目錄中並被命名爲robots.txt
。位於子目錄中的 robots.txt
文件無效,由於漫遊器只在域名的根目錄中查找此文件。例如,http://www.example.com/robots.txt
是有效位置,http://www.example.com/mysite/robots.txt
則不是有效位置web
因爲http/https
協議特性是無狀態特性,所以須要服務器在客戶端寫入cookie
,可讓服務器知道此請求是在什麼樣的狀態下發生api
cookie
簡言之就是讓服務器記錄客戶端的相關狀態信息,有兩種方式:服務器
cookie
值,而後將該值封裝到headers中headers={ 'cookie':"...." } 在發起請求時把cookie封裝進去
cookie
的值來自服務器端,在模擬登錄post
後,服務器端建立並返回給客戶端session
會話對象來操做cookie
,session
做用:能夠進行請求的發送;若是請求過程當中產生了cookie
會自動被存儲或攜帶在該session
對象中session
對象:session=requests.Session()
,使用session
對象進行模擬登錄post
請求發送(cookie
會被存儲在session
中)session
請求:session.post()
在發送時session
對象對要請求的頁面對應get
請求進行發送(攜帶了cookie
)用python
爬取數據解析原理:cookie
bs4
進行網頁數據解析
bs4
解析原理:session
BeautifulSoup
對象,而且將頁面源碼數據加載到該對象中BeautifulSoup
對象中相關的屬性或者方法進行標籤訂位和數據提取環境安裝:app
pip install bs4 pip install lxml
如何實例化BeautifulSoup
對象:
導包from bs4 import BeautifulSoup
對象的實例化,有兩種,本地和遠程:工具
html
文檔中的數據加載到該對象中fp = open('./test.html','r',encoding='utf-8') soup=BeautifulSoup(fp,'lxml') #指定lxml解析方式
page_text = response.text soup=BeautifulSoup(page_text,'lxml')
使用bs4
提供的用於數據解析的方法和屬性:post
soup.tagName
:返回的是文檔中第一次出現的tagName
對應的標籤,好比soup.a
獲取第一次出現的a
標籤信息
soup.find()
:
在使用find('tagName')
效果是等同於soup.tagName
;
進行屬性定位,soup.find(‘div’,class_(或id或attr)='song')
:示例就是定位帶有class='song'
的div
標籤,class_
必須有下劃線是爲了規避python
關鍵字
還能夠是其餘好比:soup.find(‘div’,id='song')
:定位id是song的div標籤
soup.find(‘div’,attr='song')
:定位attr是song的div標籤
soup.find_all('tagName')
:返回符合要求的全部標籤(列表)
select
用法:
select('某種選擇器(id,class,標籤..選擇器)')
返回的是一個列表獲取標籤之間文本數據
可使用text
或string
或get_text()
,主要區別:
text
或get_text()
能夠獲取某一個標籤中全部的文本內容string
:只能夠獲取該標籤下面直系的文本內容獲取標籤中屬性值:
python
獲取字典方法獲取,好比:soup.a['href']
就是獲取<a>
中的href
值import os import requests from bs4 import BeautifulSoup headers={ 'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" } url="https://www.test.com/chaxun/zuozhe/77.html" def getPoems(): res= requests.get(url=url,headers=headers) res.encoding='UTF-8' page_text=res.text #在首頁解析出章節 soup = BeautifulSoup(page_text,'lxml') shici_list = soup.select(".shici_list_main > h3 > a") shici_name=[] for li in shici_list: data_url = "https://www.test.com"+li['href'] # print(li.string+"======="+data_url) shici_name.append(li.string) detail_res = requests.get(url=data_url,headers=headers) detail_res.encoding='UTF-8' detail_page_text=detail_res.text detail_soup = BeautifulSoup(detail_page_text,'lxml') detail_content = detail_soup.find("div",class_="item_content").text # print(detail_content) with open("./shici.txt",'a+',encoding= 'utf8') as file: if shici_name.count(li.string)==1: file.write(li.string) file.write(detail_content+"\n") print(li.string+"下載完成!!!!") if __name__=="__main__": getPoems()
xpath
解析:最經常使用且最便捷高效的一種解析方式
xpath
解析原理:
etree
的對象,且須要將被解析的頁面源碼數據加載到該對象中etree
對象中的xpath
方法結合着xpath
表達式實現標籤的定位和內容的捕獲環境安裝:
pip install lxml
先實例化一個etree
對象,先導包:from lxml import etree
html
文檔中的源碼數據加載到etree
對象中tree=etree.parse(filepath)
page_text = response.text tree=etree.HTML(page_text)
經過xpath
表達式:tree.xpath(xpath表達式)
:
xpath
表達式:
/
:表示的是從根節點開始定位,表示的是一個層級//
:表示的是多個層級,能夠表示從任意位置開始定位tag[@attrName='attrValue']
//div[@class='song']
表示的是獲取到任意位置class='song'
的<div>
標籤//div[@class='song']/p[3]
表示的是任意位置class='song'
的<div>
標籤下面的第三個<p>
標籤,注意:
索引定位是從1
開始的/text()
:獲取的是標籤中直系文本內容//text()
:標籤中非直系的文本內容(全部的文本內容)/@attrName
:獲取某個屬性的值,好比://img/@src
獲取任意的img
標籤的src
值import requests from lxml import etree import re headers={ 'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" } url="https://www.test.com/chaxun/zuozhe/77.html" def getPoemsByXpath(): res= requests.get(url=url,headers=headers) res.encoding='UTF-8' page_text=res.text #在首頁解析出章節 tree = etree.HTML(page_text) shici_list = tree.xpath("//div[@class='shici_list_main']") shici_name_out='' for shici in shici_list: #此處使用相對路徑 shici_name=shici.xpath("h3/a/text()")[0] # print(shici_name) shici_text_list=shici.xpath("div//text()") # print(shici_text_list) with open("./shicibyxpath.txt",'a+',encoding= 'utf8') as file: if shici_name_out!=shici_name: file.write(shici_name+"\n") for text in shici_text_list: if "展開全文"==text or "收起"==text or re.match(r'^\s*$',text)!=None or re.match(r'^\n\s*$',text)!=None: continue re_text=text.replace(' ','').replace('\n','') file.write(re_text+"\n") if shici_name_out!=shici_name: print(shici_name+"下載完成!!!!") shici_name_out=shici_name if __name__=="__main__": getPoemsByXpath()