關于任務思考:
1.確定爬蟲入口:
start_urls = [
'http://ggglxy.scu.edu.cn/index.php?c=article&a=type&tid=18&page_1_page=1',
]
確定爬蟲入口應該是編寫爬蟲的第一步,但是很不幸抢肛,我在第一步就走偏了
狼钮,從公共管理學院首頁進到師資隊伍頁面獲得的網(wǎng)址是
但是從這個網(wǎng)址我無法獲得下一頁的絕對鏈接,在執(zhí)行爬蟲的過程中捡絮,我就遇上了URLERROR的錯誤熬芜。
- 爬取思路:
從這張圖,可以看出锦援,我們可以在目錄頁抓取教師姓名猛蔽、教師職位、教師所屬專業(yè)灵寺、教師郵箱曼库,因此我們只需要在詳情頁獲取教師的簡介就可以了筐咧。
從網(wǎng)站的目錄頁中微姊,每頁有八項數(shù)據(jù),我需要拿到每一項的數(shù)據(jù)的鏈接袱衷,同時還需要拿到「下一頁」的鏈接叮称。因為下一頁的結構和第一頁的結構相同种玛,所以我將下一頁的連接傳給pasre處理,而每一項數(shù)據(jù)的鏈接交給pasre_content處理瓤檐。
- 代碼實現(xiàn):
3.1 items.py文件:
class TeacherItem(scrapy.Item)
name = scrapy.Field() #教師姓名
position = scrapy.Field() #教師職位
intro = scrapy.Field() #教師
email = scrapy .Field() #教師郵箱
major = scrapy.Field()#教師所屬專業(yè)
pass
3.2 spider代碼:
處理目錄頁的教師信息的代碼:
def parse(self,response):
for quote in response.css('ul.teachers_ul.mt20.cf li.fl'):
item = TeacherItem()
item['name'] = quote.css('div.r.fr h3.mb10::text').extract_first()#教師名字
item['position'] = quote.css('div.r.fr p.color_main.f14::text').extract_first()#教師職位
item['major'] = quote.css('div.r.fr div.desc p::text').extract_first()#教師所屬專業(yè)
item['email'] = response.xpath('//div[@class="r fr"]/div[@class="desc"]/p[last()]/text()').extract()#教師郵箱
url = response.urljoin(quote.css('div.l.fl a::attr("href")').extract_first())#教師詳情頁鏈接
request=scrapy.http.Request(url,callback=self.parse_content)#將獲取的信息傳給詳情頁處理器
request.meta['item']=item
yield request
處理下一頁的鏈接的代碼:
next_page = response.xpath('//div[@class="pager cf tc pt10 pb10 mobile_dn"]/li[last()-1]/a/@href').extract_first() #獲取下一頁的鏈接
if next_page is not None:
next_full_url = response.urljoin(next_page)
yield scrapy.Request(next_full_url, callback=self.parse) #判斷是有有下一頁赂韵,有的話,就將url傳給自身
處理每一項數(shù)據(jù)鏈接的代碼:
def parse_content(self,response):
for site in response.css('div.js_infobox.cf'):
item = response.meta['item']#接收meta傳遞過來的數(shù)據(jù)挠蛉,即姓名祭示、郵箱、職位等信息
item['intro']= site.css('div.r.fr div.desc::text').extract_first()
yield item
在編寫這個代碼的過程中谴古,我認為元素的定位是最難的质涛,路徑不對數(shù)據(jù)就爬不出。
3.3 執(zhí)行爬蟲
同樣使用scrapy crawl quotes
命令來執(zhí)行爬蟲掰担,爬取之后下載文件汇陆,打開:
由于文件默認的是unicode編碼格式,所以我爬取到的數(shù)據(jù)是一堆我看不懂數(shù)據(jù)带饱。我首先嘗試了同學使用過并可行的
scrapy crawl quotes -o teacher.json -s FEED_EXPORT_ENCODING=utf-8
命令毡代,結果生成的還是unicode編碼格式的文件。
3.4 處理unicode編碼問題
通過網(wǎng)上查找,我運用了下面的方法解決問題:
修改pipelines.py文件:
import json
import codecs
class QuotesPipeline(object):
def __init__(self):
self.file =codecs.open('teacher.json','wb',encoding='utf-8')
def process_item(self, item, spider):
line=json.dumps(dict(item))+'\n'
self.file.write(line.decode("unicode_escape"))
return item
在pipelines.py這個文件中月趟,通過編寫QuotesPipeline來實現(xiàn)對item的處理灯蝴。它主要完成數(shù)據(jù)的查重、丟棄孝宗,驗證item中的數(shù)據(jù),將得到的item數(shù)據(jù)保存等工作耕肩。其中 process_item方法將得到的item實現(xiàn)解碼因妇,以便正常顯示中文,最終保存到json文件中猿诸。
在編寫完pipelines.py后婚被,為了啟動它,必須將其加入到ITEM_PIPELINES配置中:
ITEM_PIPELINES = {
'quotes.pipelines.QuotesPipeline':300
}
修改完這些文件后梳虽,我再次執(zhí)行spiders址芯,將得到的結果保存并下載:
這次,數(shù)據(jù)顯示正常窜觉,共抓取到了128位老師的信息谷炸,其中包括了教師的姓名、職位禀挫、所屬專業(yè)旬陡、郵箱與簡介。