美文网首页
四川大学公共管理学院新闻内容爬取

四川大学公共管理学院新闻内容爬取

作者: 不明生物lei | 来源:发表于2017-05-15 15:53 被阅读0次

    目录##

    • 任务内容
    • 爬取过程
    • 总结

    <b>任务内容</b>
    此次抓取的内容为四川大学公共管理学院新闻专栏里的新闻,包括新闻的时间、标题、图片以及详情内容。

    xinwen.png

    这是需要爬的新闻

    neirong.png

    这是新闻的详情

    yeshu.png

    这是总新闻数(目前为止)

    <b>爬取过程</b>
    1.首先创建一个新闻工程,并修改其中的items.py文件

    创建项目.jpg

    创建了一个名为“news”的项目

    gaiitems.png

    修改了items.py文件,其中的time、detail、title、picture是采集的时间、新闻详情、标题、图片。day是我采集过程中需要到的一个具体日期项(后有说明原因)。

    2.一步一步渐进的抓取过程
    秉乘着我一贯小心翼翼的态度,我的抓取过程是慢慢来的,首先是爬取一页新闻列表(不包括新闻详情里面的内容),然后开始加入多页爬取,再到爬取多页的新闻详情(虽然过程比较麻烦,但是这样的方法能够使错误发现得快,且思路较清晰,容易跟得上)。
    <p>> 2.1爬取一页新闻列表
    爬取一页新闻列表的代码就比较简单了,这也是最开始学习爬虫的时候学习的代码。
    这一步只需要采集新闻的标题和时间。

    import scrapy
    from news.items import NewsItem
    
    class newsspider(scrapy.Spider):import scrapy
        name = "news"
        start_urls = ['http://ggglxy.scu.edu.cn/index.php?c=special&sid=1']
    
        def parse(self, response):
           for new in response.xpath('//div[@class="newsinfo_box cf"]'):
                item = NewsItem()
                item['time'] = new.xpath('div[@class="date fl"]/span/text()').extract()
                item['day'] = new.xpath('div[@class="date fl"]/p/text()').extract()
                item['title'] = new.xpath('div[@class="news_c fr"]/h3[@class="mb10"]/a/text()').extract()
                yield item  
    

    解析:这是在新闻列表页爬取的时间及标题数据,在列表页,可以看到时间的“年-月”和“日”是分开的,这是因为列表页将日期做成一个日历格式的原因,所以在源代码中,他们在不同的地方。所以我在时间上用了两个参数:time、day,一个爬年月,一个爬日

    1.png
    爬取结果显示
    danye1.png
    结果中的中文显示得是乱码,百度以后查到是编码问题,随后去修改了settings.py文件。增加一行代码:
    FEED_EXPORT_ENCODING = 'utf-8'
    <p>重新爬取以后,结果就对了。
    danye2.png
    <p>> 2.2爬取多页新闻列表
    爬取多页需要加入循环爬取下一页的代码。
    import scrapy
    from news.items import NewsItem
    
    class newsspider(scrapy.Spider):
        name = "news"
        start_urls = ['http://ggglxy.scu.edu.cn/index.php?c=special&sid=1']
    
        def parse(self, response):
            for new in response.xpath('//div[@class="newsinfo_box cf"]'):
                item = NewsItem()
                item['time'] = new.xpath('div[@class="date fl"]/span/text()').extract()
                item['day'] = new.xpath('div[@class="date fl"]/p/text()').extract()
                item['title'] = new.xpath('div[@class="news_c fr"]/h3[@class="mb10"]/a/text()').extract()
                yield item
    
            next_page = response.xpath('//div[@class="pager cf tr pt10 pb10 mt30 mobile_dn"]/li[last()-1]/a/@href').extract_first()
            last_page = response.xpath('//div[@class="pager cf tr pt10 pb10 mt30 mobile_dn"]/li[last()]/a/@href').extract_first()
            if last_page is not None:
               next_page = response.urljoin(next_page)
               yield scrapy.http.Request(next_page, callback=self.parse)  
    

    解析:在爬取下一页时,发现这个网站爬的下一页有些问题

    duoye1.png
    从网站源代码的分页代码中可以看出,它的下一页是没有标志属性的,都是统一的li标签,如果在写路径的时候直接写li,爬虫是无法去按我们想的那样去爬下一页链接。这时候就需要写一些属性让爬虫识别。还好的是它的顺序都是最后一项是“尾页”,倒数第二项是“下一页”,这样只要li中增加[last()-1]的谓语,就能够顺利爬到下一页的链接。但是即使这样,还是出现一个问题。 duoye2.png
    duoye3.png

    图中可以看出,在新闻的最后一页,它没有尾页也没有下一页选项,它的倒数第二个选项是第九页。这就尴尬了,如果按照这个方法爬取,它分页循环爬取的时候,无法判断是否已经达到最后一页,最后会在第九页和第十页之间反复爬取。这时候,就需要设置一个判断,判断它是否是到了最后一页。仔细看最后一页的源代码,可以看到其最后一个li是没有链接的!!!这时候,我们可以利用这一点,判断其最后一个li是否有链接,如果没有了,它就是最后一页,停止继续爬行。

    duoye4.png

    这是爬取所有新闻的列表,共191条。

    <p>> 2.3爬取多页新闻列表详情
    爬取多页的时候仍然遇到了问题,我们需要链接链到详情页里面爬取新闻的内容和图片,这样的话需要在当前页面爬时间,爬标题,再进入链接里面爬内容。这样的话要分两个函数(是应该称为函数吗?)进行爬取,中间还有点绕。但我发现详情页面有时间和标题,突然顿悟可以直接链接进去进行需要的全部数据爬取,于是,把之前的代码改动了一些,进行爬取。

    import scrapy
    from news.items import NewsItem
    
    class newsspider(scrapy.Spider):
        name = "news"
        start_urls = ['http://ggglxy.scu.edu.cn/index.php?c=special&sid=1']
    
        def parse(self, response):
            for href in response.xpath('//div[@class="news_c fr"]/h3[@class="mb10"]/a/@href').extract():
            yield scrapy.http.Request(response.urljoin(href), callback=self.parse_news)
    
            next_page = response.xpath('//div[@class="pager cf tr pt10 pb10 mt30 mobile_dn"]/li[last()-1]/a/@href').extract_first()
            last_page = response.xpath('//div[@class="pager cf tr pt10 pb10 mt30 mobile_dn"]/li[last()]/a/@href').extract_first()
            if last_page is not None:
                next_page = response.urljoin(next_page)
                yield scrapy.http.Request(next_page, callback=self.parse)
    
        def parse_news(self, response):
            for new in response.xpath('//div[@class="right_info p20"]'):
                item = NewsItem()
                item['time'] = new.xpath('div[@class="detail_zy_title"]/p/text()').extract()
                item['title'] = new.xpath('div[@class="detail_zy_title"]/h1/text()').extract()
                item['detail'] = new.xpath('div[@class="detail_zy_c pb30 mb30"]/p/span/text()').extract()
                item['picture'] = new.xpath('div[@class="detail_zy_c pb30 mb30"]/p/img/@src').extract()
                yield item  
    

    前一个def是进入链接,然后返回到第二个def进行数据爬取。

    all.png
    这个是爬取的最终结果。其中还有几点其实应该进行完善。
    第一,图片只是一个路径,无法显示。
    第二,新闻详细内容中,有些存在较多的空格及/n、/r等乱七八糟的东西。
    但是心累了,以后再慢慢研究吧。

    <b>总结</b>
    我觉得自己这种一点一点进行的想法挺好,至少我能懂它每一块代码在做什么,也能理清他们之间的关系。这个方法效率不高,也当真花了不少的时间,但其中的收获是满满的。
    这次爬取过程懂得了分页和链接详情爬取,确实比在课堂上做的那个好得多。纠错的过程固然心累,但实践出真知,挺有道理的。
    还需要学习同时爬取当前网页及链接网页内容的方法。再接再厉吧。

    相关文章

      网友评论

          本文标题:四川大学公共管理学院新闻内容爬取

          本文链接:https://www.haomeiwen.com/subject/kutfxxtx.html