文本分类(二):scrapy爬取网易新闻

12 篇文章 0 订阅
文本分类的第一项应该就是获取文本了吧。
在木有弄懂scrapy的情况下写的,纯应用,或许后续会补上scrapy的原理。
首先说一下我的环境:ubuntu14.10
scrapy安装指南(肯定官网的最权威了):[传送门](http://scrapy-chs.readthedocs.org/zh_CN/0.24/intro/install.html#intro-install)

需要完成的任务:

  1. 创建一个Scrapy项目
  2. 定义提取的Item
  3. 编写爬取网站的Spider并提取Item
  4. 编写Item Pipeline来存储提取到的Item

正式开始

新建scrapy项目

在命令行下:

scrapy startproject tech163

执行完程序后,将会有如下结构:

tech163/
    scrapy.cfg
    tech163/
        __init__.py
        items.py
        pipelines.py
        settings.py
        spiders/
            __init__.py
            ...

定义item

打开items.py
这里写图片描述
news_thread: 定义获取新闻的进程
news_title:获取新闻标题
news_url:获取新闻地址
news_time:获取新闻发布时间
news_from:获取发布者
from_url:获取。。。
news_body:获取新闻正文

定义spider

在spider目录下新建news_spider.py。必须继承scrapy.Spider类,且需要定义以下三个属性:

  • name:用于区别Spider。该名字必须是唯一的。不可以为不同的Spider设置相同的名字。
  • start_url:包含了Spider在启动时进行爬取的URL列表。因此,第一个被获取的页面将是其中之一。后续的url则是从出事的url获取到的数据中提取。可以使用正则表达式定义和过滤需要进行跟进的链接。

  • parse():是spider的一个方法。被调用时,每个初始url完成下载后生成的response对象将会作为唯一的参数传递给该函数。该方法负责解析返回的数据、提取数据(生成item)以及生成需要进一步处理的url的response对象。

selectors选择器

scrapy使用了一种基于XPath和CSS表达式机制:Scrapy Selectors。
我们使用XPath来从页面的HTML源码中选择需要提取的数据。简单说一下XPath的用法。
  • /html/head/title:选择HTML文档中<head>标签内的<title>元素
  • /html/head/title/text():选择上面提到的<title>元素的文字
  • //td:选择所有的<td>元素
  • //div[@class=”mine”]:选择所有具有class=“mine”元素(2015/12/4/21:37)

以一篇网易的科技类的新闻进行说明:新闻网址

这里写图片描述
可以看到title是在head中的title中,因此使用XPath的形式为:/html/head/title/text()
其余的提取内容类似,需要查看网页的源代码。附上源代码(只是爬取科技类的新闻,其余的只要修改网址即可)

 #encoding: utf-8
    import scrapy
    import re
    from scrapy.selector import Selector
    from tech163.items import Tech163Item
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider,Rule
    class ExampleSpider(CrawlSpider):
        name = "news"
        allowed_domains = ["tech.163.com"] #需要对应网易新闻的类别
        start_urls = ['http://tech.163.com/']
        rules=(
            Rule(LinkExtractor(allow=r"/14/08\d+/\d+/*"), #这里需根据具体年份考虑 /14/是指年份 /08\d+/ 是指月份 这个可参考一个网易新闻的地址:http://tech.163.com/16/1119/09/C67P02V400097U81.html 
            callback="parse_news",follow=True),
        )
        def printcn(suni):
            for i in uni:
                print uni.encode('utf-8')
        def parse_news(self,response):
            item = Tech163Item()
            item['news_thread']=response.url.strip().split('/')[-1][:-5]
            # self.get_thread(response,item)
            self.get_title(response,item)
            self.get_source(response,item)
            self.get_url(response,item)
            self.get_news_from(response,item)
            self.get_from_url(response,item)
            self.get_text(response,item)
            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!remenber to Retrun Item after parse
            return item 
        def get_title(self,response,item):
            title=response.xpath("/html/head/title/text()").extract()
            if title:
                # print 'title:'+title[0][:-5].encode('utf-8')
                item['news_title']=title[0][:-5]

        def get_source(self,response,item):
            source=response.xpath("//div[@class='left']/text()").extract()
            if source:
                # print 'source'+source[0][:-5].encode('utf-8')
                item['news_time']=source[0][:-5]

        def get_news_from(self,response,item):
            news_from=response.xpath("//div[@class='left']/a/text()").extract()
            if news_from:
                # print 'from'+news_from[0].encode('utf-8')     
                item['news_from']=news_from[0]

        def get_from_url(self,response,item):
            from_url=response.xpath("//div[@class='left']/a/@href").extract()
            if from_url:
                # print 'url'+from_url[0].encode('utf-8')       
                item['from_url']=from_url[0]    

        def  get_text(self,response,item):
            news_body=response.xpath("//div[@id='endText']/p/text()").extract()
            if news_body:
                # for  entry in news_body:
                #   print entry.encode('utf-8')
                item['news_body']=news_body 
        def get_url(self,response,item):
            news_url=response.url
            if news_url:
                #print news_url 
            item['news_url']=news_url

定义Item Pipeline

在pipelin.py文件中编写自己的pipeline,简单点说就是定义爬虫爬取的内容存放的地方。

from scrapy import signals
from scrapy.exporters import XmlItemExporter
class Tech163Pipeline(object):
    def __init__(self):
        pass
    @classmethod
    def from_crawler(cls,crawler):
        pipeline = cls()
        crawler.signals.connect(pipeline.spider_opened,signals.spider_opened)
        crawler.signals.connect(pipeline.spider_closed,signals.spider_closed)
        return pipeline
    def spider_opened(self,spider):
        self.file = open("test.xml","wb")
        self.exporter = XmlItemExporter(self.file)
        self.exporter.start_exporting()
    def spider_closed(self,spider):
        self.exporter.finish_exporting()
        self.file.close()
    def process_item(self, item, spider):
        self.exporter.export_item(item)
        return item

在这里采用xml形式进行数据的存放,数据也可以存放到数据库中。

最后一步了,进行配置

万里长城,终于只差一步。
这里写图片描述

在这里等我研究了在进行解释。
最下边的USER_AGENT是使用浏览器代理,防止被禁的。(2015/12/5 11:52)

忘了写执行的命令了:
退到与工程同一目录下:

scrapy crawl news
  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值