關于任務思考:
1.確定爬蟲入口:
start_urls = [
'http://ggglxy.scu.edu.cn/index.php?c=article&a=type&tid=18&page_1_page=1',
]
確定爬蟲入口應該是編寫爬蟲的第一步,但是很不幸,我在第一步就走偏了
,從公共管理學院首頁進到師資隊伍頁面獲得的網址是
但是從這個網址我無法獲得下一頁的絕對鏈接,在執行爬蟲的過程中,我就遇上了URLERROR的錯誤。
- 爬取思路:
圖片.png
從這張圖,可以看出,我們可以在目錄頁抓取教師姓名、教師職位、教師所屬專業、教師郵箱,因此我們只需要在詳情頁獲取教師的簡介就可以了。
下一頁.png
從網站的目錄頁中,每頁有八項數據,我需要拿到每一項的數據的鏈接,同時還需要拿到「下一頁」的鏈接。因為下一頁的結構和第一頁的結構相同,所以我將下一頁的連接傳給pasre處理,而每一項數據的鏈接交給pasre_content處理。
- 代碼實現:
3.1 items.py文件:
class TeacherItem(scrapy.Item)
name = scrapy.Field() #教師姓名
position = scrapy.Field() #教師職位
intro = scrapy.Field() #教師
email = scrapy .Field() #教師郵箱
major = scrapy.Field()#教師所屬專業
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()#教師所屬專業
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傳給自身
處理每一項數據鏈接的代碼:
def parse_content(self,response):
for site in response.css('div.js_infobox.cf'):
item = response.meta['item']#接收meta傳遞過來的數據,即姓名、郵箱、職位等信息
item['intro']= site.css('div.r.fr div.desc::text').extract_first()
yield item
在編寫這個代碼的過程中,我認為元素的定位是最難的,路徑不對數據就爬不出。
3.3 執行爬蟲
同樣使用scrapy crawl quotes
命令來執行爬蟲,爬取之后下載文件,打開:
數據.png
由于文件默認的是unicode編碼格式,所以我爬取到的數據是一堆我看不懂數據。我首先嘗試了同學使用過并可行的
scrapy crawl quotes -o teacher.json -s FEED_EXPORT_ENCODING=utf-8
命令,結果生成的還是unicode編碼格式的文件。
3.4 處理unicode編碼問題
通過網上查找,我運用了下面的方法解決問題:
修改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來實現對item的處理。它主要完成數據的查重、丟棄,驗證item中的數據,將得到的item數據保存等工作。其中 process_item方法將得到的item實現解碼,以便正常顯示中文,最終保存到json文件中。
在編寫完pipelines.py后,為了啟動它,必須將其加入到ITEM_PIPELINES配置中:
ITEM_PIPELINES = {
'quotes.pipelines.QuotesPipeline':300
}
修改完這些文件后,我再次執行spiders,將得到的結果保存并下載:
圖片.png
這次,數據顯示正常,共抓取到了128位老師的信息,其中包括了教師的姓名、職位、所屬專業、郵箱與簡介。