scrapy爬取学院新闻信息实例

爬取工作开展思路:

首先打开川大公共管理学院首页,浏览其信息确定需要爬取的信息;再使用浏览器的开发者工具,确定需要爬取的数据的具体路径;之后使用 scrapy shell 来测试xpath或者css的表达式是否正确;最后编写scrapy代码爬取数据。

1.需要爬取哪些数据

《scrapy爬取学院新闻信息实例》 1.png

我定义的数据爬取是直接在首页显示的这12条新闻动态,首先需要在首页获取到新闻文章的标题以及它的url地址。

《scrapy爬取学院新闻信息实例》 12.jpg

打开新闻详情页,确定需要在该页面爬取的数据:标题和内容文本。

2.用开发者工具确定xpath表达式,并检验

《scrapy爬取学院新闻信息实例》 学院首页html

被黄线标明的信息是我想获取的数据,获取具有class属性且其值为fl的a标签里的url地址,所以xpath表达式为:

//a[@class="fl"]/@href

《scrapy爬取学院新闻信息实例》 新闻详情页html

在新闻详情页,想得到的数据是标题和文章内容,可以看到标题在 h1标签内,其xpath表达式是:

//div[@class="detail_zv_title"]/h1/text()

《scrapy爬取学院新闻信息实例》 新闻详情页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(),

        }

执行代码后,得到是:

《scrapy爬取学院新闻信息实例》 4.PNG

不太理想的是它爬取的数据是这样的:

《scrapy爬取学院新闻信息实例》 image.png

但是,输出为xml文件显示出来的是正常的中文,如果输出为json文件又变成了unicode编码。

4.爬取过程中遇到的问题

4.1关于定义item的问题

《scrapy爬取学院新闻信息实例》 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文件,这个问题就得到解决了,它是正常显示的中文。我也觉得这是一件很神奇的事情。

《scrapy爬取学院新闻信息实例》 7.PNG

爬取工作开展思路:

首先打开川大公共管理学院首页,浏览其信息确定需要爬取的信息;再使用浏览器的开发者工具,确定需要爬取的数据的具体路径;之后使用 scrapy shell 来测试xpath或者css的表达式是否正确;最后编写scrapy代码爬取数据。

1.需要爬取哪些数据

《scrapy爬取学院新闻信息实例》 1.png

我定义的数据爬取是直接在首页显示的这12条新闻动态,首先需要在首页获取到新闻文章的标题以及它的url地址。

《scrapy爬取学院新闻信息实例》 12.jpg

打开新闻详情页,确定需要在该页面爬取的数据:标题和内容文本。

2.用开发者工具确定xpath表达式,并检验

《scrapy爬取学院新闻信息实例》 学院首页html

被黄线标明的信息是我想获取的数据,获取具有class属性且其值为fl的a标签里的url地址,所以xpath表达式为:

//a[@class="fl"]/@href

《scrapy爬取学院新闻信息实例》 新闻详情页html

在新闻详情页,想得到的数据是标题和文章内容,可以看到标题在 h1标签内,其xpath表达式是:

//div[@class="detail_zv_title"]/h1/text()

《scrapy爬取学院新闻信息实例》 新闻详情页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(),

        }

执行代码后,得到是:

《scrapy爬取学院新闻信息实例》 4.PNG

不太理想的是它爬取的数据是这样的:

《scrapy爬取学院新闻信息实例》 image.png

但是,输出为xml文件显示出来的是正常的中文,如果输出为json文件又变成了unicode编码。

4.爬取过程中遇到的问题

4.1关于定义item的问题

《scrapy爬取学院新闻信息实例》 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文件,这个问题就得到解决了,它是正常显示的中文。我也觉得这是一件很神奇的事情。

《scrapy爬取学院新闻信息实例》 7.PNG

    原文作者:不会唱歌的我
    原文地址: https://www.jianshu.com/p/e4d39296c5ac
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞