爬取工作開展思路:
首先打開川大公共管理學院首頁,瀏覽其信息確定需要爬取的信息;再使用瀏覽器的開發者工具,確定需要爬取的數據的具體路徑;之后使用 scrapy shell 來測試xpath或者css的表達式是否正確;最后編寫scrapy代碼爬取數據。
1.需要爬取哪些數據
我定義的數據爬取是直接在首頁顯示的這12條新聞動態,首先需要在首頁獲取到新聞文章的標題以及它的url地址。
打開新聞詳情頁,確定需要在該頁面爬取的數據:標題和內容文本。
2.用開發者工具確定xpath表達式,并檢驗
被黃線標明的信息是我想獲取的數據,獲取具有class屬性且其值為fl的a標簽里的url地址,所以xpath表達式為:
//a[@class="fl"]/@href
在新聞詳情頁,想得到的數據是標題和文章內容,可以看到標題在 h1標簽內,其xpath表達式是:
//div[@class="detail_zv_title"]/h1/text()
新聞詳情頁中,文章內容在p標簽下的<span>標簽中,其xpath表達式為:
//p[@class="MsoNormal"]/span/text()
3.編寫news_spider.py文件
import scrapy
class StackOverflowSpider(scrapy.Spider):
name = 'news'
start_urls = ['http://ggglxy.scu.edu.cn/']
def parse(self, response):
for href in response.xpath('//a[@class="fl"]/@href'):
url = response.urljoin(href.extract())
yield scrapy.Request(url, callback=self.parse_news)
def parse_news(self, response):
yield {
'title': response.xpath('//div[@class="detail_zy_title"]/h1/text()').extract(),
'content': response.xpath('//p[@class="MsoNormal"]/span/text()').extract(),
}
執行代碼后,得到是:
不太理想的是它爬取的數據是這樣的:
但是,輸出為xml文件顯示出來的是正常的中文,如果輸出為json文件又變成了unicode編碼。
4.爬取過程中遇到的問題
4.1關于定義item的問題
我在創建scrapy爬取工程時,并沒有自定義item文件,因為在編寫news_spider.py并沒有用到它,但還是成功爬取了信息。所以我現在也不太清楚是否一定到去定義item文件,去定義它有什么好處。
4.2xpath表達式定義出錯導致爬取的數據變少了
我在爬取新聞詳情頁時,發現只爬取到了一條文章的內容,之后才發現是
'content': response.xpath('//p[@align="left"]/span/text()').extract()
這一行出錯,我這一句是根據第一篇文章編寫,原以為每篇文章的align屬性的值都是left,之后檢查發現,只有第一篇符合。所以導致,只爬取定義一篇文章的內容。
之后改為
'content': response.xpath('//p[@class="MsoNormal"]/span/text()').extract()
發現每篇文章到被抓取到了。
4.3中文爬取輸出Unicode編碼
我爬取的信息在終端上顯示出來是這樣的
2017-05-15 22:44:30 [scrapy.core.scraper] DEBUG: Scraped from <200 http://ggglxy.scu.edu.cn/index.php?c=article&id=915>
{'content': [u'2017', u'\u5e74', u'3', u'\u6708', u'24', u'\u65e5\u4e0b\u5348\uff0c\u7f8e\u56fd\u534e\u76db\u987f\u5927\u5b66\u827e\u4e39\u526f\u6559\u6388\uff08', u'Daniel Abramson', u'\uff09\u5b66\u672f\u8bb2\u5ea7\u300a\u90fd\u6c5f\u5830\u704c\u533a\u7684\u957f\u671f\u793e\u4f1a\u751f\u6001\u97e7\u6027\u53ca\u5176\u5bf9\u571f\u5730\u653f\u7b56\u3001\u6751\u843d\u89c4\u5212\u548c\u793e\u533a\u6cbb\u7406\u7684\u542f\u793a\u300b\uff08', u'Long-term Social-Ecological Resilience in the Dujiangyan Irrigation District:\r\nImplications for Land Policy, Settlement Planning, and Community Governance', u'\uff09\u5728\u516c\u5171\u7ba1\u7406\u5b66\u9662', u'214', u'\u6210\u529f\u4e3e\u529e\u3002\u56db\u5ddd\u5927\u5b66\u516c\u5171\u7ba1\u7406\u5b66\u9662\u5218\u6da6\u79cb\u6559\u6388\u4e3b\u6301\u4e86\u6b64\u6b21\u8bb2\u5ea7\uff0c\u571f\u5730\u8d44\u6e90\u4e0e\u623f\u5730\u4ea7\u7ba1\u7406\u7cfb\u9a6c\u7231\u6167\u526f\u6559\u6388\u3001\u571f\u5730\u8d44\u6e90\u7ba1\u7406\u
并不是顯示的中文,包括輸出的json文件也是這種樣子,查詢網上信息得到的結果是需要去修改目錄下pipelines.py 文件為:
import json
import codecs
class FilterWordsPipeline(object):
def __init__(self):
# self.file = open('data.json', 'wb')
self.file = codecs.open(
'scraped_data_utf8.json', 'w', encoding='utf-8')
def process_item(self, item, spider):
line = json.dumps(dict(item), ensure_ascii=False) + "\n"
self.file.write(line)
return item
def spider_closed(self, spider):
self.file.close()
但我有按照它說的去修改問題并沒有得到解決,自己研究出來了兩種辦法:一種是網上有在線的unicode轉換工具可以轉換為中文;另外一種是將爬取到信息不再導出為json文件而是xml文件,這個問題就得到解決了,它是正常顯示的中文。我也覺得這是一件很神奇的事情。
爬取工作開展思路:
首先打開川大公共管理學院首頁,瀏覽其信息確定需要爬取的信息;再使用瀏覽器的開發者工具,確定需要爬取的數據的具體路徑;之后使用 scrapy shell 來測試xpath或者css的表達式是否正確;最后編寫scrapy代碼爬取數據。
1.需要爬取哪些數據
我定義的數據爬取是直接在首頁顯示的這12條新聞動態,首先需要在首頁獲取到新聞文章的標題以及它的url地址。
打開新聞詳情頁,確定需要在該頁面爬取的數據:標題和內容文本。
2.用開發者工具確定xpath表達式,并檢驗
被黃線標明的信息是我想獲取的數據,獲取具有class屬性且其值為fl的a標簽里的url地址,所以xpath表達式為:
//a[@class="fl"]/@href
在新聞詳情頁,想得到的數據是標題和文章內容,可以看到標題在 h1標簽內,其xpath表達式是:
//div[@class="detail_zv_title"]/h1/text()
新聞詳情頁中,文章內容在p標簽下的<span>標簽中,其xpath表達式為:
//p[@class="MsoNormal"]/span/text()
3.編寫news_spider.py文件
import scrapy
class StackOverflowSpider(scrapy.Spider):
name = 'news'
start_urls = ['http://ggglxy.scu.edu.cn/']
def parse(self, response):
for href in response.xpath('//a[@class="fl"]/@href'):
url = response.urljoin(href.extract())
yield scrapy.Request(url, callback=self.parse_news)
def parse_news(self, response):
yield {
'title': response.xpath('//div[@class="detail_zy_title"]/h1/text()').extract(),
'content': response.xpath('//p[@class="MsoNormal"]/span/text()').extract(),
}
執行代碼后,得到是:
不太理想的是它爬取的數據是這樣的:
但是,輸出為xml文件顯示出來的是正常的中文,如果輸出為json文件又變成了unicode編碼。
4.爬取過程中遇到的問題
4.1關于定義item的問題
我在創建scrapy爬取工程時,并沒有自定義item文件,因為在編寫news_spider.py并沒有用到它,但還是成功爬取了信息。所以我現在也不太清楚是否一定到去定義item文件,去定義它有什么好處。
4.2xpath表達式定義出錯導致爬取的數據變少了
我在爬取新聞詳情頁時,發現只爬取到了一條文章的內容,之后才發現是
'content': response.xpath('//p[@align="left"]/span/text()').extract()
這一行出錯,我這一句是根據第一篇文章編寫,原以為每篇文章的align屬性的值都是left,之后檢查發現,只有第一篇符合。所以導致,只爬取定義一篇文章的內容。
之后改為
'content': response.xpath('//p[@class="MsoNormal"]/span/text()').extract()
發現每篇文章到被抓取到了。
4.3中文爬取輸出Unicode編碼
我爬取的信息在終端上顯示出來是這樣的
2017-05-15 22:44:30 [scrapy.core.scraper] DEBUG: Scraped from <200 http://ggglxy.scu.edu.cn/index.php?c=article&id=915>
{'content': [u'2017', u'\u5e74', u'3', u'\u6708', u'24', u'\u65e5\u4e0b\u5348\uff0c\u7f8e\u56fd\u534e\u76db\u987f\u5927\u5b66\u827e\u4e39\u526f\u6559\u6388\uff08', u'Daniel Abramson', u'\uff09\u5b66\u672f\u8bb2\u5ea7\u300a\u90fd\u6c5f\u5830\u704c\u533a\u7684\u957f\u671f\u793e\u4f1a\u751f\u6001\u97e7\u6027\u53ca\u5176\u5bf9\u571f\u5730\u653f\u7b56\u3001\u6751\u843d\u89c4\u5212\u548c\u793e\u533a\u6cbb\u7406\u7684\u542f\u793a\u300b\uff08', u'Long-term Social-Ecological Resilience in the Dujiangyan Irrigation District:\r\nImplications for Land Policy, Settlement Planning, and Community Governance', u'\uff09\u5728\u516c\u5171\u7ba1\u7406\u5b66\u9662', u'214', u'\u6210\u529f\u4e3e\u529e\u3002\u56db\u5ddd\u5927\u5b66\u516c\u5171\u7ba1\u7406\u5b66\u9662\u5218\u6da6\u79cb\u6559\u6388\u4e3b\u6301\u4e86\u6b64\u6b21\u8bb2\u5ea7\uff0c\u571f\u5730\u8d44\u6e90\u4e0e\u623f\u5730\u4ea7\u7ba1\u7406\u7cfb\u9a6c\u7231\u6167\u526f\u6559\u6388\u3001\u571f\u5730\u8d44\u6e90\u7ba1\u7406\u
并不是顯示的中文,包括輸出的json文件也是這種樣子,查詢網上信息得到的結果是需要去修改目錄下pipelines.py 文件為:
import json
import codecs
class FilterWordsPipeline(object):
def __init__(self):
# self.file = open('data.json', 'wb')
self.file = codecs.open(
'scraped_data_utf8.json', 'w', encoding='utf-8')
def process_item(self, item, spider):
line = json.dumps(dict(item), ensure_ascii=False) + "\n"
self.file.write(line)
return item
def spider_closed(self, spider):
self.file.close()
但我有按照它說的去修改問題并沒有得到解決,自己研究出來了兩種辦法:一種是網上有在線的unicode轉換工具可以轉換為中文;另外一種是將爬取到信息不再導出為json文件而是xml文件,這個問題就得到解決了,它是正常顯示的中文。我也覺得這是一件很神奇的事情。