第一次實戰,我們以博客園為例。
Cnblog是典型的靜態網頁,通過查看博文的源代碼,可以看出很少js代碼,連css代碼也比較簡單,很適合爬蟲初學者來練習。
博客園的栗子,我們的目標是獲取某個博主的所有博文,今天先將第一步。
第一步:已知某一篇文章的url,如何獲取正文?
舉個栗子,我們參考‘農民伯伯’的博客文章吧,哈哈。他是我關注的一個博主。
http://www.cnblogs.com/over140/p/4440137.html
這是他的一篇名為“【讀書筆記】長尾理論”的文章。
我們如果想要存儲這篇文章,需要保存的內容首先是文章的標題,再就是文章的正文。
文章的標題怎么獲取的?
先看一下文章標題在網頁源代碼中的位置是如何的。
可以看出來,標題的文字內容是包含在一個a標簽里面的,我們將這個標簽打印出來:
<a id="cb_post_title_url" class="postTitle2" href="http://www.cnblogs.com/over140/p/4440137.html">【讀書筆記】長尾理論</a>
那個標簽具有id屬性,值為“cb_post_title_url”,具有class屬性,值為“postTitle2”,還具有一個href屬性,指向了這篇文章的url。
這個標簽應該是比較方便定位的,所以文章標題我們能夠很快找到。
代碼如下:
import urllib.request import re url='http://www.cnblogs.com/over140/p/4440137.html' req=urllib.request.Request(url) resp=urllib.request.urlopen(req) html_page=resp.read().decode('utf-8') title_pattern=r'(<a.*id="cb_post_title_url".*>)(.*)(</a>)' title_match=re.search(title_pattern,html_page) title=title_match.group(2) #print(title)
上面的title就是我們想要爬取的這篇文章的代碼
文章的正文如何獲取呢?
來看一下文章的結構,正文的所有內容都在一個div標簽里面,但是這個div中存在很多其他標簽,並不是直接一堆文字放在div標簽里面。比如有很多<p></p>標簽,比如<strong>標簽。
如何獲取所有的內容呢?
我猜測,只要將所有><之間的內容,應該就可以獲得所有的正文內容。試一下,代碼如下:
div_pattern=r'<div id="cnblogs_post_body">(.*)</div>' div_match=re.search(div_pattern,html_page) div=div_match.group(1) #print(div) result_pattern=r'>(.*)<' result_match=re.findall(result_pattern,div) result='' for i in result_match: result+=str(i) print(result)
遺憾的是,失敗了。。。打印出來的內容,不僅包含文字,還有一些包含在內的標簽,比如<span>。
用正則表達式的缺陷這里就體現出來了。。我們還是用BeautifulSoup來解析文檔吧。
使用BeautifulSoup解析內容的方法,請回顧我所寫的爬蟲入門的文章。
獲取正文所在的div標簽的代碼如下:
from bs4 import BeautifulSoup soup=BeautifulSoup(html_page,'html.parser') #print(soup.prettify()) div=soup.find(id="cnblogs_post_body") #print(div.text) print(div.get_text())
哈哈,大功告成,我們獲得了正文的內容。為了便於保存,我們將文章保存到當前目錄下。
filename=title+'.txt' with open(filename,'w',encoding='utf-8') as f: f.write(div.text)
OK了,至此為止,我們獲取並保存了這篇文章。
來,所有的代碼如下所示:
import urllib.request import re from bs4 import BeautifulSoup url='http://www.cnblogs.com/over140/p/4440137.html' req=urllib.request.Request(url) resp=urllib.request.urlopen(req) html_page=resp.read().decode('utf-8') title_pattern=r'(<a.*id="cb_post_title_url".*>)(.*)(</a>)' title_match=re.search(title_pattern,html_page) title=title_match.group(2) #print(title) ''' div_pattern=r'<div id="cnblogs_post_body">(.*)</div>' div_match=re.search(div_pattern,html_page) div=div_match.group(1) #print(div) result_pattern=r'>(.*)<' result_match=re.findall(result_pattern,div) result='' for i in result_match: result+=str(i) print(result) ''' soup=BeautifulSoup(html_page,'html.parser') #print(soup.prettify()) div=soup.find(id="cnblogs_post_body") #print(div.text) print(div.get_text()) filename=title+'.txt' with open(filename,'w',encoding='utf-8') as f: f.write(div.text)