爬取工作开展思路:
首先打开川大公共管理学院首页,浏览其信息确定需要爬取的信息;再使用浏览器的开发者工具,确定需要爬取的数据的具体路径;之后使用 scrapy shell 来测试xpath或者css的表达式是否正确;最后编写scrapy代码爬取数据。
1.需要爬取哪些数据
1.png我定义的数据爬取是直接在首页显示的这12条新闻动态,首先需要在首页获取到新闻文章的标题以及它的url地址。
12.jpg
打开新闻详情页,确定需要在该页面爬取的数据:标题和内容文本。
2.用开发者工具确定xpath表达式,并检验
学院首页html被黄线标明的信息是我想获取的数据,获取具有class属性且其值为fl的a标签里的url地址,所以xpath表达式为:
//a[@class="fl"]/@href
新闻详情页html
在新闻详情页,想得到的数据是标题和文章内容,可以看到标题在 h1标签内,其xpath表达式是:
//div[@class="detail_zv_title"]/h1/text()
新闻详情页html
新闻详情页中,文章内容在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(),
}
执行代码后,得到是:
4.PNG
不太理想的是它爬取的数据是这样的:
image.png但是,输出为xml文件显示出来的是正常的中文,如果输出为json文件又变成了unicode编码。
4.爬取过程中遇到的问题
4.1关于定义item的问题
6.PNG我在创建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文件,这个问题就得到解决了,它是正常显示的中文。我也觉得这是一件很神奇的事情。
7.PNG爬取工作开展思路:
首先打开川大公共管理学院首页,浏览其信息确定需要爬取的信息;再使用浏览器的开发者工具,确定需要爬取的数据的具体路径;之后使用 scrapy shell 来测试xpath或者css的表达式是否正确;最后编写scrapy代码爬取数据。
1.需要爬取哪些数据
1.png我定义的数据爬取是直接在首页显示的这12条新闻动态,首先需要在首页获取到新闻文章的标题以及它的url地址。
12.jpg
打开新闻详情页,确定需要在该页面爬取的数据:标题和内容文本。
2.用开发者工具确定xpath表达式,并检验
学院首页html被黄线标明的信息是我想获取的数据,获取具有class属性且其值为fl的a标签里的url地址,所以xpath表达式为:
//a[@class="fl"]/@href
新闻详情页html
在新闻详情页,想得到的数据是标题和文章内容,可以看到标题在 h1标签内,其xpath表达式是:
//div[@class="detail_zv_title"]/h1/text()
新闻详情页html
新闻详情页中,文章内容在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(),
}
执行代码后,得到是:
4.PNG
不太理想的是它爬取的数据是这样的:
image.png但是,输出为xml文件显示出来的是正常的中文,如果输出为json文件又变成了unicode编码。
4.爬取过程中遇到的问题
4.1关于定义item的问题
6.PNG我在创建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文件,这个问题就得到解决了,它是正常显示的中文。我也觉得这是一件很神奇的事情。
7.PNG
网友评论