前面我們已經說了那麼多基礎知識了,下面我們做個實戰項目來挑戰一下吧。這次就用前面學的urllib和正規表達式來做,Python爬蟲爬取糗事百科的小段子。
爬取前我們先看一下我們的目标:
1.抓取糗事百科熱門段子
2.過濾帶有圖檔的段子
3.段子的釋出人,段子内容,好笑數,評論數
1.确定URL并抓取頁面代碼
首先我們确定好頁面的URL,糗事百科的網址是:http://www.qiushibaike.com,但是這個URL不友善我們後面連續抓取,我們可以看一下第二頁就知道URL如何構造了,URL是 http://www.qiushibaike.com/8hr/page/1/?s=4872200,其中中間的數字1代表頁數,我們可以傳入不同的值來獲得某一頁的段子内容,其他的部分是不變的。
我們先看看最基本的頁面抓取方式,看看會不會成功
import urllib2
page=1
url = 'http://www.qiushibaike.com/8hr/page/'+str(page)+'/?s=4872200'
try:
request = urllib2.Request(url)
response = urllib2.urlopen(request)
print response.read()
except urllib2.URLError, e:
if hasattr(e,"code"):
print e.code
if hasattr(e,"reason"):
print e.reason
結果出現 raise BadStatusLine(line) httplib.BadStatusLine: '',我們需要加上headers驗證,如下:
import urllib2
page=1
url = 'http://www.qiushibaike.com/8hr/page/'+str(page)+'/?s=4872200'
user_agent ='Mozilla/4.0(compatible;MSIE 5.5;Windows NT)'
headers={'User-Agent':user_agent}
try:
request = urllib2.Request(url,headers = headers)
response = urllib2.urlopen(request)
print response.read()
except urllib2.URLError, e:
if hasattr(e,"code"):
print e.code
if hasattr(e,"reason"):
print e.reason
好啦,運作正常,頁面代碼也列印出來了。
2、用正規表達式提取段子
我們先看審查元素,看一下代碼,如下圖:
每個段子都在一個盒子裡,<div class="article block untagged mb15" id="qiushi_tag_116124511"><div class="author clearfix">...</div> 現在我們需要 段子的釋出人,段子内容,好笑數,評論數,用正規表達式比對如下:
content = response.read().decode('utf-8')
pattern = re.compile('<div.*?author clearfix">.*?<a.*?<img.*?>.*?</a>.*?<a.*?>.*?<h2>(.*?)</h2>.*?content">'+
'(.*?)</div>.*?<div class="stats">.*?vote".*?number">(.*?)</i>.*?stats-comments".*?<a.*?number">(.*?)</i>',re.S)
items = re.findall(pattern,content)
for item in items :
print item[0],item[1],item[2],item[3]
看一下爬出來的段子:
好啦下面我們把代碼完整的留下,加了一個小循環,爬取10頁:
# _*_ coding:utf-8 _*_
import urllib2
import re
page=1
print u"第%d頁"%page
while page < 10:
url = 'http://www.qiushibaike.com/8hr/page/' + str(page) + '/?s=4872200'
user_agent ='Mozilla/4.0(compatible;MSIE 5.5;Windows NT)'
headers={'User-Agent':user_agent}
try:
request = urllib2.Request(url,headers = headers)
response = urllib2.urlopen(request)
content = response.read().decode('utf-8')
pattern = re.compile('<div.*?author clearfix">.*?<a.*?<img.*?>.*?</a>.*?<a.*?>.*?<h2>(.*?)</h2>.*?content">' +
'(.*?)</div>.*?<div class="stats">.*?vote".*?number">(.*?)</i>.*?stats-comments".*?<a.*?number">(.*?)</i>',re.S)
items = re.findall(pattern,content)
for item in items :
print item[0],item[1],item[2],item[3]
except urllib2.URLError, e:
if hasattr(e,"code"):
print e.code
if hasattr(e,"reason"):
print e.reason
page = page + 1
print u"第%d頁"%page
好啦,代碼比較糙,大家可以自己試試!