目錄##
-
任務內容
-
爬取過程
-
總結
<b>任務內容</b>
此次抓取的內容為四川大學公共管理學院新聞專欄里的新聞觅玻,包括新聞的時間垢箕、標題站辉、圖片以及詳情內容呢撞。
這是需要爬的新聞
這是新聞的詳情
這是總新聞數(shù)(目前為止)
<b>爬取過程</b>
1.首先創(chuàng)建一個新聞工程,并修改其中的items.py文件
創(chuàng)建了一個名為“news”的項目
修改了items.py文件饰剥,其中的time殊霞、detail、title汰蓉、picture是采集的時間绷蹲、新聞詳情、標題顾孽、圖片祝钢。day是我采集過程中需要到的一個具體日期項(后有說明原因)。
2.一步一步漸進的抓取過程
秉乘著我一貫小心翼翼的態(tài)度若厚,我的抓取過程是慢慢來的拦英,首先是爬取一頁新聞列表(不包括新聞詳情里面的內容),然后開始加入多頁爬取测秸,再到爬取多頁的新聞詳情(雖然過程比較麻煩龄章,但是這樣的方法能夠使錯誤發(fā)現(xiàn)得快,且思路較清晰乞封,容易跟得上)做裙。
<p>> 2.1爬取一頁新聞列表
爬取一頁新聞列表的代碼就比較簡單了,這也是最開始學習爬蟲的時候學習的代碼肃晚。
這一步只需要采集新聞的標題和時間锚贱。
import scrapy
from news.items import NewsItem
class newsspider(scrapy.Spider):import scrapy
name = "news"
start_urls = ['http://ggglxy.scu.edu.cn/index.php?c=special&sid=1']
def parse(self, response):
for new in response.xpath('//div[@class="newsinfo_box cf"]'):
item = NewsItem()
item['time'] = new.xpath('div[@class="date fl"]/span/text()').extract()
item['day'] = new.xpath('div[@class="date fl"]/p/text()').extract()
item['title'] = new.xpath('div[@class="news_c fr"]/h3[@class="mb10"]/a/text()').extract()
yield item
解析:這是在新聞列表頁爬取的時間及標題數(shù)據(jù),在列表頁关串,可以看到時間的“年-月”和“日”是分開的拧廊,這是因為列表頁將日期做成一個日歷格式的原因,所以在源代碼中晋修,他們在不同的地方吧碾。所以我在時間上用了兩個參數(shù):time、day墓卦,一個爬年月倦春,一個爬日
爬取結果顯示
結果中的中文顯示得是亂碼,百度以后查到是編碼問題,隨后去修改了settings.py文件睁本。增加一行代碼:
FEED_EXPORT_ENCODING = 'utf-8'
<p>重新爬取以后尿庐,結果就對了。
<p>> 2.2爬取多頁新聞列表
爬取多頁需要加入循環(huán)爬取下一頁的代碼呢堰。
import scrapy
from news.items import NewsItem
class newsspider(scrapy.Spider):
name = "news"
start_urls = ['http://ggglxy.scu.edu.cn/index.php?c=special&sid=1']
def parse(self, response):
for new in response.xpath('//div[@class="newsinfo_box cf"]'):
item = NewsItem()
item['time'] = new.xpath('div[@class="date fl"]/span/text()').extract()
item['day'] = new.xpath('div[@class="date fl"]/p/text()').extract()
item['title'] = new.xpath('div[@class="news_c fr"]/h3[@class="mb10"]/a/text()').extract()
yield item
next_page = response.xpath('//div[@class="pager cf tr pt10 pb10 mt30 mobile_dn"]/li[last()-1]/a/@href').extract_first()
last_page = response.xpath('//div[@class="pager cf tr pt10 pb10 mt30 mobile_dn"]/li[last()]/a/@href').extract_first()
if last_page is not None:
next_page = response.urljoin(next_page)
yield scrapy.http.Request(next_page, callback=self.parse)
解析:在爬取下一頁時抄瑟,發(fā)現(xiàn)這個網站爬的下一頁有些問題
從網站源代碼的分頁代碼中可以看出,它的下一頁是沒有標志屬性的枉疼,都是統(tǒng)一的li標簽皮假,如果在寫路徑的時候直接寫li,爬蟲是無法去按我們想的那樣去爬下一頁鏈接骂维。這時候就需要寫一些屬性讓爬蟲識別钞翔。還好的是它的順序都是最后一項是“尾頁”,倒數(shù)第二項是“下一頁”席舍,這樣只要li中增加[last()-1]的謂語,就能夠順利爬到下一頁的鏈接哮笆。但是即使這樣来颤,還是出現(xiàn)一個問題。
圖中可以看出稠肘,在新聞的最后一頁福铅,它沒有尾頁也沒有下一頁選項,它的倒數(shù)第二個選項是第九頁项阴。這就尷尬了滑黔,如果按照這個方法爬取,它分頁循環(huán)爬取的時候环揽,無法判斷是否已經達到最后一頁略荡,最后會在第九頁和第十頁之間反復爬取。這時候歉胶,就需要設置一個判斷汛兜,判斷它是否是到了最后一頁。仔細看最后一頁的源代碼通今,可以看到其最后一個li是沒有鏈接的V嗝!辫塌!這時候漏策,我們可以利用這一點,判斷其最后一個li是否有鏈接臼氨,如果沒有了掺喻,它就是最后一頁,停止繼續(xù)爬行。
這是爬取所有新聞的列表巢寡,共191條喉脖。
<p>> 2.3爬取多頁新聞列表詳情
爬取多頁的時候仍然遇到了問題,我們需要鏈接鏈到詳情頁里面爬取新聞的內容和圖片抑月,這樣的話需要在當前頁面爬時間树叽,爬標題,再進入鏈接里面爬內容谦絮。這樣的話要分兩個函數(shù)(是應該稱為函數(shù)嗎题诵?)進行爬取,中間還有點繞层皱。但我發(fā)現(xiàn)詳情頁面有時間和標題性锭,突然頓悟可以直接鏈接進去進行需要的全部數(shù)據(jù)爬取,于是叫胖,把之前的代碼改動了一些践樱,進行爬取。
import scrapy
from news.items import NewsItem
class newsspider(scrapy.Spider):
name = "news"
start_urls = ['http://ggglxy.scu.edu.cn/index.php?c=special&sid=1']
def parse(self, response):
for href in response.xpath('//div[@class="news_c fr"]/h3[@class="mb10"]/a/@href').extract():
yield scrapy.http.Request(response.urljoin(href), callback=self.parse_news)
next_page = response.xpath('//div[@class="pager cf tr pt10 pb10 mt30 mobile_dn"]/li[last()-1]/a/@href').extract_first()
last_page = response.xpath('//div[@class="pager cf tr pt10 pb10 mt30 mobile_dn"]/li[last()]/a/@href').extract_first()
if last_page is not None:
next_page = response.urljoin(next_page)
yield scrapy.http.Request(next_page, callback=self.parse)
def parse_news(self, response):
for new in response.xpath('//div[@class="right_info p20"]'):
item = NewsItem()
item['time'] = new.xpath('div[@class="detail_zy_title"]/p/text()').extract()
item['title'] = new.xpath('div[@class="detail_zy_title"]/h1/text()').extract()
item['detail'] = new.xpath('div[@class="detail_zy_c pb30 mb30"]/p/span/text()').extract()
item['picture'] = new.xpath('div[@class="detail_zy_c pb30 mb30"]/p/img/@src').extract()
yield item
前一個def是進入鏈接敷硅,然后返回到第二個def進行數(shù)據(jù)爬取虱饿。
這個是爬取的最終結果。其中還有幾點其實應該進行完善绷跑。
第一拳恋,圖片只是一個路徑,無法顯示砸捏。
第二谬运,新聞詳細內容中,有些存在較多的空格及/n垦藏、/r等亂七八糟的東西梆暖。
但是心累了,以后再慢慢研究吧掂骏。
<b>總結</b>
我覺得自己這種一點一點進行的想法挺好式廷,至少我能懂它每一塊代碼在做什么,也能理清他們之間的關系芭挽。這個方法效率不高滑废,也當真花了不少的時間,但其中的收獲是滿滿的袜爪。
這次爬取過程懂得了分頁和鏈接詳情爬取蠕趁,確實比在課堂上做的那個好得多。糾錯的過程固然心累辛馆,但實踐出真知俺陋,挺有道理的豁延。
還需要學習同時爬取當前網頁及鏈接網頁內容的方法。再接再厲吧腊状。