目錄:
Report B1——采集川大公管學(xué)院新聞動態(tài)信息
1.確定采集內(nèi)容
2.創(chuàng)建爬取項(xiàng)目
3.定義spider
3.1編寫item.py文件
3.2本地編寫spiders文件并上傳
4.執(zhí)行爬蟲并保存數(shù)據(jù)
Report B2——采集川大公管學(xué)院全職教師信息
5.總結(jié)
Report B1——采集川大公管學(xué)院新聞動態(tài)信息
1.確定采集內(nèi)容
在進(jìn)行一項(xiàng)采集任務(wù)的時(shí)候,我們不能一開始就寫代碼吧(當(dāng)然观蜗,你想先搭個(gè)基本的框架還是可以的)但是要實(shí)現(xiàn)內(nèi)容的爬取,你總不能隨便寫個(gè)路徑去爬取吧,所以稿壁,首先羹奉,你就得明確要爬取的內(nèi)容诈闺,分析網(wǎng)頁的內(nèi)容:
分頁列表:
可知,這個(gè)爬取的內(nèi)容涉及到了分頁的問題称鳞,初步設(shè)想是我們需要得到下一頁的鏈接和每一項(xiàng)的鏈接。
新聞內(nèi)容詳情頁:
所以稠鼻,確定采集內(nèi)容為:標(biāo)題(title)冈止,日期(date),具體內(nèi)容(details)候齿。
2.創(chuàng)建爬取項(xiàng)目(news為項(xiàng)目名稱)
3.定義spider
3.1編寫item.py文件
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NewsItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
date = scrapy.Field()
details = scrapy.Field()
3.2本地編寫spiders文件并上傳(因?yàn)槲移陂g改了很多次代碼熙暴,這里只展示了最終版本,關(guān)于分頁以及頁面地址傳值的內(nèi)容已注釋在代碼之中)
import scrapy
from news.items import NewsItem
class NewsSpider(scrapy.Spider):
"""
name:scrapy唯一定位實(shí)例的屬性,必須唯一
allowed_domains:允許爬取的域名列表慌盯,不設(shè)置表示允許爬取所有
start_urls:起始爬取列表
start_requests:它就是從start_urls中讀取鏈接周霉,然后使用make_requests_from_url生成Request,
這就意味我們可以在start_requests方法中根據(jù)我們自己的需求往start_urls中寫入
我們自定義的規(guī)律的鏈接
parse:回調(diào)函數(shù)亚皂,處理response并返回處理后的數(shù)據(jù)和需要跟進(jìn)的url
"""
# 設(shè)置name
name = "nspider"
# 設(shè)定域名
allowed_domains = ["ggglxy.scu.edu.cn"]
# 填寫爬取地址
start_urls = [
'http://ggglxy.scu.edu.cn/index.php?c=special&sid=1',
]
def parse(self,response):
for href in response.xpath("http://ul[@class='newsinfo_list_ul mobile_dn']/li/div/div[@class='news_c fr']/h3/a/@href"):
url = response.urljoin(href.extract())
## 將得到的頁面地址傳送給單個(gè)頁面處理函數(shù)進(jìn)行處理 -> parse_details()
yield scrapy.Request(url,callback=self.parse_details)
## 是否還有下一頁俱箱,如果有的話,則繼續(xù)
next_page=response.xpath("http://div[@class='pager cf tr pt10 pb10 mt30 mobile_dn']/li[last()-1]/a/@href").extract_first()
if next_page is not None:
next_pages = response.urljoin(next_page)
## 將 「下一頁」的鏈接傳遞給自身灭必,并重新分析
yield scrapy.Request(next_pages, callback = self.parse)
# 編寫爬取方法
def parse_details(self, response):
#for line in response.xpath("http://ul[@class='newsinfo_list_ul mobile_dn']"):
# 初始化item對象保存爬取的信息
item = NewsItem()
# 這部分是爬取部分狞谱,使用xpath的方式選擇信息,具體方法根據(jù)網(wǎng)頁結(jié)構(gòu)而定
item['title'] = response.xpath("http://div[@class='detail_zy_title']/h1/text()").extract()
item['date'] = response.xpath("http://div[@class='detail_zy_title']/p/text()").extract()
item['details'] = response.xpath("http://div[@class='detail_zy_c pb30 mb30']/p/span/text()").extract()
yield item
參考鏈接:
SCRAPY爬蟲框架入門實(shí)例(一)
Scrapy 學(xué)習(xí)筆記 -- 解決分頁爬取的問題
XPath教程
注:在路徑的選擇時(shí)可以采用開發(fā)者工具查看網(wǎng)頁源碼:
4.執(zhí)行爬蟲并保存數(shù)據(jù)
剛開始執(zhí)行代碼的過程中禁漓,出現(xiàn)了一些問題跟衅,第一個(gè)問題是:
SyntaxError: invalid syntax
表示的意思是其中有中文的輸入嫂拴,按照提示信息吨艇,仔細(xì)查看news.py文件中的第23行,發(fā)現(xiàn)我的單引號是在中文模式下輸入的尼斧,是說怎么打出來的時(shí)候顯示出來的感覺很奇怪荚恶,在修改了之后又遇到了第二個(gè)問題:
IndentationError: unexpected indent
表示的意思是縮進(jìn)的問題撩穿,python是一種對縮進(jìn)非常敏感的語言,最常見的情況是tab和空格的混用會導(dǎo)致錯誤谒撼,或者縮進(jìn)不對食寡,我使用的就是最笨的辦法,就是一行一行的重新調(diào)整廓潜。
還出現(xiàn)過:
ImportError: No module named items
這個(gè)錯誤抵皱,百度出來說是spiders 目錄中的.py文件不能和項(xiàng)目名同名善榛。后來仔細(xì)看了一下,發(fā)現(xiàn)我確實(shí)出現(xiàn)了這個(gè)問題呻畸,我的項(xiàng)目名稱是news移盆,我的spiders 目錄中的.py文件也是news.py,這就出現(xiàn)了同名的情況伤为,后來我把.py文件的名字改成了spidernews.py咒循,雖然名字比較長,但是比較直觀绞愚。
當(dāng)然叙甸,最難的問題是路徑的選擇,但是由于在做的過程中沒有進(jìn)行記錄位衩,而且對于不同的采集任務(wù)涉及到的路徑選擇問題也是不同的裆蒸,所以也就沒有必要進(jìn)行舉例了。一定要記得路徑一定要選對L锹俊A诺弧!
在所有錯誤解決之后遂赠,執(zhí)行爬蟲久妆,保存json文件,執(zhí)行代碼:
scrapy crawl nspider -o news.json
但是一開始保存下來的文件顯示不是中文跷睦,如圖所示:
這是因?yàn)榭晗遥瑸榱烁玫膫鬏斨形模琷son進(jìn)行了Unicode編碼抑诸。這樣一來烂琴,我們在解析json之前,就得要先將json數(shù)據(jù)中的Unicode編碼轉(zhuǎn)換為我們使用的中文蜕乡。有同學(xué)反映她們也遇到了這個(gè)問題奸绷,就嘗試了她們說的百度到的方法,執(zhí)行代碼:
scrapy crawl nspider -o news.json -s FEED_EXPORT_ENCODING=utf-8
來實(shí)現(xiàn)輸出的json格式文件直接顯示中文层玲。
參考鏈接:Scrapy 爬取中文內(nèi)容后的編碼問題
或者在執(zhí)行爬蟲之前在settings.py文件代碼行
SPIDER_MODULES = ['news.spiders']
NEWSPIDER_MODULE = 'news.spiders'
之后添加以下代碼:
FEED_EXPORT_ENCODING = 'utf-8'
即
SPIDER_MODULES = ['news.spiders']
NEWSPIDER_MODULE = 'news.spiders'
FEED_EXPORT_ENCODING = 'utf-8'
參考鏈接:Unicode編碼轉(zhuǎn)為中文
最后得到理想的結(jié)果号醉,一共191條數(shù)據(jù)。部分截圖如下:
Report B2——采集川大公管學(xué)院全職教師信息
采集的內(nèi)容是:教師姓名辛块,職位畔派,簡介。
思路同采集新聞動態(tài)信息的思路一樣润绵。
spiderteachers.py
import scrapy
from teachers.items import TeachersItem
class TeachersSpider(scrapy.Spider):
"""
name:scrapy唯一定位實(shí)例的屬性线椰,必須唯一
allowed_domains:允許爬取的域名列表,不設(shè)置表示允許爬取所有
start_urls:起始爬取列表
start_requests:它就是從start_urls中讀取鏈接尘盼,然后使用make_requests_from_url生成Request憨愉,
這就意味我們可以在start_requests方法中根據(jù)我們自己的需求往start_urls中寫入
我們自定義的規(guī)律的鏈接
parse:回調(diào)函數(shù)烦绳,處理response并返回處理后的數(shù)據(jù)和需要跟進(jìn)的url
"""
# 設(shè)置name
name = "tspider"
# 設(shè)定域名
allowed_domains = ["ggglxy.scu.edu.cn"]
# 填寫爬取地址
start_urls = [
'http://ggglxy.scu.edu.cn/index.php?c=article&a=type&tid=18&page_1_page=1',
]
def parse(self,response):
for href in response.xpath("http://div[@class='l fl']/a/@href"):
url = response.urljoin(href.extract())
## 將得到的頁面地址傳送給單個(gè)頁面處理函數(shù)進(jìn)行處理 -> parse_details()
yield scrapy.Request(url,callback=self.parse_details)
## 是否還有下一頁,如果有的話配紫,則繼續(xù)
next_page=response.xpath("http://div[@class='pager cf tc pt10 pb10 mobile_dn']/li[last()-1]/a/@href").extract_first()
if next_page is not None:
next_pages = response.urljoin(next_page)
## 將 「下一頁」的鏈接傳遞給自身径密,并重新分析
yield scrapy.Request(next_pages, callback = self.parse)
# 編寫爬取方法
def parse_details(self, response):
#for line in response.xpath("http://ul[@class='newsinfo_list_ul mobile_dn']"):
# 初始化item對象保存爬取的信息
item = TeachersItem()
# 這部分是爬取部分,使用xpath的方式選擇信息笨蚁,具體方法根據(jù)網(wǎng)頁結(jié)構(gòu)而定
item['name'] = response.xpath("http://div[@class='r fr']/h3/text()").extract()
item['position'] = response.xpath("http://div[@class='r fr']/p/text()").extract()
item['details'] = response.xpath("http://div[@class='r fr']/div/text()").extract()
yield item
爬取結(jié)果部分截圖:
共128名全職教師信息睹晒。
5.總結(jié)
一旦涉及到代碼趟庄,就一定要仔細(xì)啊括细,認(rèn)真啊,不然有可能就因?yàn)橐粋€(gè)數(shù)字戚啥,或者一個(gè)字母就可以讓你花幾個(gè)小時(shí)甚至有可能幾天都找不出來錯誤奋单,甚至讓你懷疑人生,受盡折磨T_T猫十。
輸入的時(shí)候記得要在英文模式下輸入览濒,英文字母倒是只有英文能夠輸入,所以要特別注意的就是標(biāo)點(diǎn)符號什么的拖云。Python的縮進(jìn)也是個(gè)麻煩事贷笛,在編寫過程中也要記得千萬不要空格和tab標(biāo)簽混用了,還有宙项,就是項(xiàng)目名稱和.py文件不能同名乏苦,雖然遇到了也不是什么大問題,但是一開始注意到這個(gè)問題也就省一些麻煩嘛尤筐。前面說到的都是些小case汇荐,最麻煩的還是爬取路徑的問題,那就只有認(rèn)真盆繁、耐心掀淘、仔細(xì)了。認(rèn)真學(xué)習(xí)爬取規(guī)則油昂,認(rèn)真分析爬取路徑革娄。