获取信息

修改items.py如下:

import scrapy


class TutorialItem(scrapy.Item):

    # define the fields for your item here like:

    # name = scrapy.Field()

    city = scrapy.Field()

    date = scrapy.Field()  

    dayDesc = scrapy.Field()  

    dayTemp = scrapy.Field() 


爬虫代码

内容如下,采用的项目还是之前创建的Tutorial/weather.py

import scrapy

from tutorial.items import TutorialItem

from scrapy.selector import Selector

from scrapy.http import Request

headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'}


class Douban(scrapy.Spider):

    name = 'weather'

    allowed_domains = ['sina.com.cn']

    start_urls = ['http://weather.sina.com.cn/hangzhou']


    def parse(self,response):

        item = TutorialItem()

        item['city'] = response.xpath("//*[@id='slider_ct_name']/text()").extract()

        tenDay = response.xpath('//*[@id="blk_fc_c0_scroll"]');

        item['date'] = tenDay.css('p.wt_fc_c0_i_date::text').extract()

        item['dayDesc'] = tenDay.css('img.icons0_wt::attr(title)').extract()

        item['dayTemp'] = tenDay.css('p.wt_fc_c0_i_temp::text').extract()

        return item

说明:

name: 用于区别Spider。该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。

start_urls: 包含了Spider在启动时进行爬取的url列表。因此,第一个被获取到的页面将是其中之一。后续的URL则从初始的URL获取到的数据中提取。

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

分析源码发现:

  • 城市名可以通过获取id为slider_ct_name的h4元素获取
  • 日期可以通过获取id为blk_fc_c0_scroll下的class为wt_fc_c0_i_date的p元素获取
  • 天气描述可以通过获取id为blk_fc_c0_scroll下的class为icons0_wt的img元素获取
  • 温度可以通过获取id为blk_fc_c0_scroll下的class为wt_fc_c0_i_temp的p元素获取

其中:

//*:选取文档中的所有元素。@:选择属性 /:从节点选取 。extract():提取




Pipeline

    当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。

    每个item pipeline组件(有时称之为“Item Pipeline”)是实现了简单方法的Python类。他们接收到Item并通过它执行一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。

以下是item pipeline的一些典型应用:

清理HTML数据

验证爬取的数据(检查item包含某些字段)

查重(并丢弃)

将爬取结果保存到数据库中

process_item(self, item, spider)

    每个item pipeline组件都需要调用该方法,这个方法必须返回一个 Item (或任何继承类)对象, 或是抛出 DropItem 异常,被丢弃的item将不会被之后的pipeline组件所处理。

参数:

item (Item 对象) – 被爬取的item

spider (Spider 对象) – 爬取该item的spider

open_spider(self, spider)

    当spider被开启时,这个方法被调用。

参数: spider (Spider 对象) – 被开启的spider

close_spider(spider)

    当spider被关闭时,这个方法被调用

参数: spider (Spider 对象) – 被关闭的spider

from_crawler(cls, crawler)

PIPELINE代码

编辑pipelines.py

class TutorialPipeline(object):

    def __init__(self):

        pass


    def process_item(self, item, spider):

        with open('wea.txt', 'w+') as file:

            city = item['city'][0].encode('utf-8')

            file.write('city:' + str(city) + '\n\n')


            date = item['date']


            desc = item['dayDesc']

            dayDesc = desc[1::2]

            nightDesc = desc[0::2]


            dayTemp = item['dayTemp']


            weaitem = zip(date, dayDesc, nightDesc, dayTemp)


            for i in range(len(weaitem)):

                item = weaitem[i]

                d = item[0]

                dd = item[1]

                nd = item[2]

                ta = item[3].split('/')

                dt = ta[0]

                nt = ta[1]

                txt = 'date:{0}\t\tday:{1}({2})\t\tnight:{3}({4})\n\n'.format(

                    d,

                    dd.encode('utf-8'),

                    dt.encode('utf-8'),

                    nd.encode('utf-8'),

                    nt.encode('utf-8')

                )

                file.write(txt)

        return item


 

    写好ITEM_PIPELINES后,还有很重要的一步,就是把 ITEM_PIPELINES 添加到设置文件 settings.py 中。

ITEM_PIPELINES = {

    'tutorial.pipelines.TutorialPipeline': 1

}

另外,有些网站对网络爬虫进行了阻止(注:本项目仅从技术角度处理此问题,个人强烈不建议您用爬虫爬取有版权信息的数据),我们可以在设置中修改一下爬虫的 USER_AGENT 和 Referer 信息,增加爬虫请求的时间间隔。

DEBUG

显示只有城市:

        scrapy内置的html解析是基于lxml库的,这个库对html的解析的容错性不是很好,通过检查网页源码,发现有部分标签是不匹配的(地区和浏览器不同取到的源码可能不同)

换个html代码解析器就可以了,这里建议用 BeautifulSoup

https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.html 

下载链接:

https://www.crummy.com/software/BeautifulSoup/bs4/download/4.5/ 

爬虫代码如下:

import scrapy

from tutorial.items import TutorialItem

from scrapy.selector import Selector

from scrapy.http import Request

from bs4 import BeautifulSoup

headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'}


class Douban(scrapy.Spider):  

    name = "weather"

    allowed_domains = ["sina.com.cn"]

    start_urls = ['http://weather.sina.com.cn']


    def parse(self, response):

        html_doc = response.body

        #html_doc = html_doc.decode('utf-8')

        soup = BeautifulSoup(html_doc)

        itemTemp = {}

        itemTemp['city'] = soup.find(id='slider_ct_name')

        tenDay = soup.find(id='blk_fc_c0_scroll')

        itemTemp['date'] = tenDay.findAll("p", {"class": 'wt_fc_c0_i_date'})

        itemTemp['dayDesc'] = tenDay.findAll("img", {"class": 'icons0_wt'})

        itemTemp['dayTemp'] = tenDay.findAll('p', {"class": 'wt_fc_c0_i_temp'})

        item = TutorialItem()

        for att in itemTemp:

            item[att] = []

            if att == 'city':

                item[att] = itemTemp.get(att).text

                continue

            for obj in itemTemp.get(att):

                if att == 'dayDesc':

                    item[att].append(obj['title'])

                else:

                    item[att].append(obj.text)

        return item