qq纵横四海源码_【0基础】纵横中文网python爬虫实战
原文在此~
【0基礎】縱橫中文網python爬蟲實戰?mp.weixin.qq.com大家好,我是你們的機房老哥!
在粉絲群的日常交流中,爬蟲是比較常見的話題。python最強大的功能之一也是爬蟲。
考慮到很多0基礎的小白想要入門爬蟲。老哥今天就通過一個比較簡單的爬蟲,介紹一下python爬蟲的流程及思路,并掃盲爬蟲常用工具的語法。
本次教程您將學到:
- 爬蟲思路、流程
- xpath全解析
- css選擇器全解析
- requests_html庫進階
話不多說,接下來就是:
-STUDY PYTHON WITH-
基礎教程——縱橫中文python爬蟲
-OLDER BROTHER-
獲取小說信息
http://book.zongheng.com/store.html
▲縱橫中文網要爬取的網址如上圖所示。
導入老哥最常用的爬蟲庫requests_html庫,首先將HTMLSession()函數定義為session。使用session.get()命令提交響應,最后打印r.html.html查看網頁源代碼。
from requests_html import HTMLSessionsession = HTMLSession() url = 'http://book.zongheng.com/store.html' r = session.get(url) print(r.html.html)▲打印網頁源碼如上圖所示,老哥已經成功獲得網頁源碼了。說明網站的反爬手段比較弱,適合新手練習。
▲分析網址結構按F12打開控制臺,可以看到左側小說的信息在<div class="bookbox fl" </div>下,右側小說的信息在<div class="bookbox fr" </div>下。網址結構非常簡單。
▲分析小說名稱我們點入每個小說信息的div下,獲取小說的信息。
可以看到,<div class="bookname">標簽下的a標簽中,href是小說網址,內容是小說標題。
<div class="booklink">標簽下的第一個a標簽中,href是作者的介紹頁網址,內容是作者筆名。第二個a標簽中,href是小說分類主題頁網址,內容是小說分類。第一個span中是小說連載狀態,第二個span中是小說更新時間。
接下來通過xpath分別提取這些信息,代碼如下:
bookname = r.html.xpath('//div[@class="bookname"]/a/text()') bookname_links = r.html.xpath('//div[@class="bookname"]/a/@href') authorname = r.html.xpath('//div[@class="bookilnk"]/a/text()') author_links = r.html.xpath('//div[@class="bookilnk"]/a/@href') typename = r.html.xpath('//div[@class="bookilnk"]/a[2]/text()') type_links = r.html.xpath('//div[@class="bookilnk"]/a[2]/@href') status = r.html.xpath('//div[@class="bookilnk"]/span/text()') time_ = r.html.xpath('//div[@class="bookilnk"]/span[2]/text()') for num in range(len(bookname_links)):print(bookname[num], bookname_links[num], authorname[num], author_links[num], typename[num], type_links[num],status[num].strip(), time_[num].strip())解析上述代碼:通過r.html.xpath調用庫中自帶的xpath語法提取小說名。//div代表任意位置的div標簽,[@class="bookname"]是xpath語法,中括號中@符號后是div的屬性,這里用div的標簽class="bookname"定位到小說名稱。/a代表這個div下的第一個a標簽,最后用text()函數提取a標簽內容,即小說標題。
提取網址方法類似,區別在于在a標簽后接/@href提取a標簽下的href屬性。
當一個div標簽下有兩個a標簽時,a[2]代表第二個a標簽。
▲獲取小說信息這里順便掃盲一下xpath的基礎語法:
詳解xpath
選取節點:
- xpath('/div')——從根節點上選取div節點。
- xpath('//div')——選取所有div節點。
- xpath('./div')——選取當前節點下的div節點。
- xpath('../a')——選取當前的父節點下的第一個a節點。
謂語:
功能函數:
- xpath('//div[starts-with(@id,"ma")]')——選取id值以ma開頭的div節點。
- xpath('//div[contains(@id,"ma")]')——選取id值包含ma的div節點。
- xpath('//div[contains(@id,"ma") and contains(@id,"in")]')——選取id值包含ma和in的div節點。
- xpath('//div[contains(text(),"ma")]')——選取文本中包含ma的節點。
在這里老哥在稍微拓展一下。獲得小說鏈接,除了上文中的方式,還可以用如下代碼:
bookname_links = r.html.xpath('//div[@class="bookname"]/a', first=True) print(bookname_links.attrs['href'])解析一下上述代碼,使用first=True提取div下的第一個a標簽。在這里用.attrs['href']命令提取a標簽下的href屬性,同樣可以得到鏈接。
值得注意的是,first=True提取的是第一個標簽,返回element格式。如果不加,則返回列表格式,就不能使用該方法了。
▲方法2獲得href下的鏈接▲方法2獲得href下的鏈接進入小說內容頁
上文中已經提取到小說的鏈接,我們只需要再次用session.get()命令請求這個鏈接,即可得到小說內容。
▲小說詳情頁不過,上文中提出的鏈接點進去是小說詳情頁,所以想要獲取小說內容,還需要提取“開始閱讀”對應的href鏈接。代碼如下:
bookname_links = r.html.xpath('//div[@class="bookname"]/a/@href') for num in range(len(bookname_links)):bookname_link = bookname_links[num]r = session.get(bookname_link)r2 = r.html.xpath('//div[contains(@class,"btn-group")]/child::a')[0].linksprint(r2)解析上述代碼:老哥為了拓展教程,用了第三種方式提取鏈接。首先解析xpath語法,//div[contains(@class,"btn-group")],代表獲取包含"btn-group"的class屬性的div節點。這種方式的好處在于,假如該div節點的class有很多,寫起來比較復雜,就可以用contains獲取該class中包含的某個唯一字段。/child::a代表該div下的第一個子節點a。
由于這種方式得到的是一個列表,提取列表的第一個值,該值包含小說鏈接。這個值是<class 'requests_html.Element'>類型,這種類型是requests_html庫自帶的類型,可以使用.links命令提取該requests_html.Element下的所有鏈接。因為本案例只有一個鏈接,所以就返回一個值,即小說的鏈接。
上述代碼中的r2即小說內容頁的鏈接。
進階:requests_html的.links命令
為了更好的理解.links命令的強大之處,老哥附帶一個小案例。例如用.links命令提取根網站下的所有網址,代碼如下:
from requests_html import HTMLSession session = HTMLSession() url = 'http://book.zongheng.com/store.html' r = session.get(url) print(r.html.links)▲輕松獲取所有鏈接可以看到,如果請求的網址下有很多網址,用.links命令可以不費吹灰之力的得到他們。
有時一些鏈接只有后半部分,需要拼接網站的域名才能使用,這時候,只需要將.links改成.absolute_links,即可獲得自動補全的所有鏈接。
小說內容提取
最后一步就是小說內容提取,方法和上文類似,就不贅述了。這個網站有趣的地方在于禁止左鍵、右鍵點擊。如果不會爬蟲,只會復制粘貼網頁信息的話,就會被難住了。當然用爬蟲就完全無視這種“小伎倆”啦。
▲小說內容▲小說內容這部分和上文類似,解析標題、內容所在位置,為了拓展教程,老哥這里使用css選擇器。代碼如下:
r3 = session.get(list(r2)[0]) title = r3.html.find('.title_txtbox', first=True).text author = r3.html.find('.bookinfo', first=True).text content = r3.html.find('.content', first=True).text解析上述代碼,r3.html.find()代表使用css選擇器。.title_txtbox代表選擇class為title_txtbox的值,.是css選擇器中選擇class類型的符號。最后用.text命令獲取內容,類似.links命令。
掃盲一下css選擇器的基礎語法:
詳解CSS選擇器
- .intro——選擇class="intro"的所有元素。
- #firstname——選擇id="firstname"的所有元素。
- *——選擇所有元素。
- p——選擇所有<p>元素。
- div,p——選擇所有<div>元素和所有<p>元素。
- divp——選擇<div>元素內部的所有<p>元素。
- div>p——選擇父元素為<div>元素的所有<p>元素。
- div+p——選擇緊接在<div>元素之后的所有<p>元素。
- [target]——選擇帶有target屬性所有元素。
- [target=_blank]——選擇target="_blank"的所有元素。
- [title~=flower]——選擇title屬性包含單詞"flower"的所有元素。
- [lang|=en]——選擇lang屬性值以"en"開頭的所有元素。
- a:link——選擇所有未被訪問的鏈接。
- a:visited——選擇所有已被訪問的鏈接。
- a:active——選擇活動鏈接。
- a:hover——選擇鼠標指針位于其上的鏈接。
- input:focus——選擇獲得焦點的input元素。
- p:first-letter——選擇每個<p>元素的首字母。
- p:first-line——選擇每個<p>元素的首行。
- p:first-child——選擇屬于父元素的第一個子元素的每個<p>元素。
- p:before——在每個<p>元素的內容之前插入內容。
- p:after——在每個<p>元素的內容之后插入內容。
- p:lang(it)——選擇帶有以"it"開頭的lang屬性值的每個<p>元素。
- p~ul——選擇前面有<p>元素的每個<ul>元素。
- a[src^="https"]——選擇其src屬性值以"https"開頭的每個<a>元素。
- a[src$=".pdf"]——選擇其src屬性以".pdf"結尾的所有<a>元素。
- a[src*="abc"]——選擇其src屬性中包含"abc"子串的每個<a>元素。
- p:first-of-type——選擇屬于其父元素的首個<p>元素的每個<p>元素。
- p:last-of-type——選擇屬于其父元素的最后<p>元素的每個<p>元素。
- p:only-of-type——選擇屬于其父元素唯一的<p>元素的每個<p>元素。
- p:only-child——選擇屬于其父元素的唯一子元素的每個<p>元素。
- p:nth-child(2)——選擇屬于其父元素的第二個子元素的每個<p>元素。
- p:nth-last-child(2)——同上,從最后一個子元素開始計數。
- p:nth-of-type(2)——選擇屬于其父元素第二個<p>元素的每個<p>元素。
- p:nth-last-of-type(2)——同上,但是從最后一個子元素開始計數。
- p:last-child——選擇屬于其父元素最后一個子元素每個<p>元素。
- :root——選擇文檔的根元素。
- p:empty——選擇沒有子元素的每個<p>元素(包括文本節點)。
- #news:target——選擇當前活動的#news元素。
- input:enabled——選擇每個啟用的<input>元素。
- input:disabled——選擇每個禁用的<input>元素
- input:checked——選擇每個被選中的<input>元素。
- :not(p)——選擇非<p>元素的每個元素。
- ::selection——選擇被用戶選取的元素部分。
翻頁
▲翻頁這里涉及到翻頁,因為小說只有下一頁,沒有具體頁數,所以只能循環讀取下一頁來不停的獲取小說內容。
nextchapter = list(r3.html.find('.nextchapter', first=True).links)[0]獲取到下一頁網址后,寫一個循環來獲取下一頁,直到無法獲取,則爬取完一本小說的所有內容。
for i in range(100000):try:name = session.get(nextchapter)title = name.html.find('.title_txtbox', first=True).textauthor = name.html.find('.bookinfo', first=True).textcontent = name.html.find('.content', first=True).textnextchapter = list(name.html.find('.nextchapter', first=True).links)[0]print(title,'n', content)except:break解析上述代碼,設定一個極大的值,讓程序不斷循環,獲取每頁的小說,直到最后一頁,無法獲取小說內容時,break跳出循環,并開啟一本新的小說的爬取。
▲爬到的小說內容欣賞一下最終的成果吧!
這樣一個基礎爬蟲教程就結束了,是不是很簡單呢!
總結
以上是生活随笔為你收集整理的qq纵横四海源码_【0基础】纵横中文网python爬虫实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 进制转换c语言代码_奇怪的C语言代码,有
- 下一篇: python不同目录调用_python3