pip install requests pip install beautifulsoup4
request是URL的擷取套件,能夠用postputgetdelete來存取網絡資源css
import requests newurl = '目標網站' res = requests.get(newurl) res.encoding = 'utf-8' # 申明編碼避免res內容出現亂碼
經過request的get獲得了網頁的全部內容,可是還有不少不須要用到的樣式語言等,原本能夠用正則表達式來進行刪選,可是這裏使用第三方包BeautifulSoup4對原材料進行處理。html
soup = BeautifulSoup(res.text,'html.parser') # 須要註釋res的類型是HTML,使用parser對HTML進行解析。
這裏須要稍微瞭解一點HTML/CSS裏的DOM Tree知識。
(注:DOM Tree是指經過DOM將HTML頁面進行解析,並生成的HTML tree樹狀結構和對應訪問方法。)python
這方面我本身是理解的,可是理解的不透徹講不清。詳參這裏
總之,咱們所須要的內容是在各類各樣的元素中的,它們多是含有特定標籤的HTML元素,也有多是含有特定CSS屬性的元素。(我所理解的是HTML元素是HTML固有的,結構層次已經劃分好了的。而特定CSS屬性的元素則是由於特殊的格式須要設置的靈活性的一個元素。通常是經過id和類來設置。)
select
爲了獲得特定的元素,使用beautifulsoup4中的select。
使用方法是:web
# 含有特定標籤的HTML元素 header = soup.select('h1') # 含有特定css屬性的元素 ID header = soup.select('#title') # 含有特定css屬性的元素 class link = soup.select('.link')
select的預設方法是傳回一個list,因此用解開列表的方式解開而且取出來就能夠。正則表達式
infoLite插件下載地址
接下來,咱們就須要知道爬取目標的元素究竟是什麼。有兩種方法,一是藉助infoLite插件,一是藉助開發工具的elements本身查找。爲了保證查找的準確性,兩種方法最好都掌握。
首先是使用infoLite插件,點擊就能夠知道元素的類型。可是有時候狀況會比較複雜,好比說,會遇到css類裏使用HTML元素的狀況。在這種狀況下先select CSS 最大共性元素再select出HTML元素。chrome
標題網絡
(網頁其餘部分也有h2,能夠結合開發工具看更清晰。)app
時間
.time工具
連接
URL連接能夠從上面的DOM Tree看到URL是元素的屬性,因此須要經過開發工具看。在網頁的連接中一般使用a tag去連接其餘網頁,而href就是連結的橋樑。post
列表裏實際上是一個字典,利用字典的性質,用key(href)調用出連接。
import requests from bs4 import BeautifulSoup res = requests.get('http://news.sina.com.cn/china/') res.encoding = 'utf-8' soup = BeautifulSoup(res.text,'html.parser') for news in soup.select('.news-item'): if len(news.select('h2'))>0: #保證存在,防止遍歷時輸出空集 h2 = news.select('h2')[0].text #取出內容 time = news.select('.time')[0].text a = news.select('a')[0]['href'] print (time,h2,a)
學習參考自此網站
在前面咱們已經將新聞列表頁面的全部連接都下載下來了,可是還不夠,咱們但願能夠獲取連接所指的各個單個新聞的標題、來源、時間以及內文。
這裏咱們從特殊到通常,而用到的方法仍是筆記NO.1中對select的活用,先以一個連接爲例。
和抓取列表頁面的初始步驟同樣,咱們首先要將原材料整個的放到soup裏進行一個剖析,而後再逐個提取出咱們想要的元素。取得頁面的說明再也不贅述。
import requests from bs4 import BeautifulSoup res = requests.get('http://news.sina.com.cn/c/nd/2017-01-04/doc-ifxzczff3681310.shtml') res.encoding = 'utf-8' soup = BeautifulSoup(res.text,'html.parser')
經過檢查工具得知標題是一個特殊的css屬性標籤,ID是artibodyTitle,經過soup的select傳回一個list,再經過取出list裏內容的方法取出來。
title= soup.select('#artibodyTitle')[0].text
原本想處理時間,時間的類是time-source,結果select回傳的結果裏既有時間又有來源。使用.text也沒法將之分開。
select的回傳列表結果:
[<span class="time-source" id="navtimeSource">2017年01月04日09:47 <span> <span data-sudaclick="media_name"> \<a href="http://www.cma.gov.cn/2011zwxx/2 011zyjgl/2011zyjxy/2011zqxyj/201701/\t20170104_382215.html \" rel="nofollow" target="_blank">政府網站</a></span></span> </span>]
因此這裏要採用contents將時間和來源取出來。
tag的.contents屬性能夠將tag的子節點以列表的方式輸出。新聞的時間精確到日就能夠了,對字符串進行切片處理。
time = soup.select('.time-source')[0].contents[:10]
接下來咱們要思考如何取出來源,經過檢查工具咱們能夠看到,來源是在時間的層級之下的,這也很好的解釋了爲何用contens處理下來,和來源有關的東西並無發生變化,由於它是附屬其下,而且由一個span裏的a tag控制的。
![Uploading time-source_539741.png . . .]
因此試試用這個把它select出來
medianame = soup.select('.time-source span a')[0].text
內文位於artibody p裏,一樣的方法取出。觀察由三個成分組成,<p>分隔符、控制符以及咱們須要的文字內容。經過strip去除控制符,再遍歷輸出
article = soup.select('#artibody p')[:-1]
同理,略
author = soup.select('.article-editor')[0].text.strip('責任編輯:')