日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

基于scrapy爬虫的天气数据采集(python)

發(fā)布時(shí)間:2024/4/13 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于scrapy爬虫的天气数据采集(python) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

基于scrapy爬蟲的天氣數(shù)據(jù)采集(python)

一、實(shí)驗(yàn)介紹

1.1. 知識(shí)點(diǎn)

本節(jié)實(shí)驗(yàn)中將學(xué)習(xí)和實(shí)踐以下知識(shí)點(diǎn):

  • Python基本語(yǔ)法
  • Scrapy框架
  • 爬蟲的概念
  • 二、實(shí)驗(yàn)效果

    三、項(xiàng)目實(shí)戰(zhàn)

    3.1. 安裝Scrapy

    安裝 scrapy-0.24:

    # 安裝依賴的包 $ sudo apt-get update $ sudo apt-get install python-lxml python-dev libffi-dev# 更新系統(tǒng)默認(rèn)的 six 包 $ sudo pip install six --upgrade# 安裝指定版本的scrapy $ sudo pip install scrapy==0.24.4

    完成這步后,可以用下面的命令測(cè)試一下安裝是否正確:

    $ scrapy version

    如果正常,效果如圖所示:

    3.2. 創(chuàng)建項(xiàng)目

    在開始爬取之前,必須創(chuàng)建一個(gè)新的Scrapy項(xiàng)目。進(jìn)入您打算存儲(chǔ)代碼的目錄中,運(yùn)行下列命令:

    $ scrapy startproject weather

    如果正常,效果如圖所示:

    這些文件分別是:

    • scrapy.cfg: 項(xiàng)目的配置文件
    • weather/: 該項(xiàng)目的python模塊。之后將在此加入代碼。
    • weather/items.py: 項(xiàng)目中的item文件.
    • weather/pipelines.py: 項(xiàng)目中的pipelines文件.
    • weather/settings.py: 項(xiàng)目的設(shè)置文件.
    • weather/spiders/: 放置spider代碼的目錄.

    3.3. 定義Item

    Item 是保存爬取到的數(shù)據(jù)的容器;其使用方法和python字典類似,并且提供了額外保護(hù)機(jī)制來(lái)避免拼寫錯(cuò)誤導(dǎo)致的未定義字段錯(cuò)誤。

    首先根據(jù)需要從weather.sina.com.cn獲取到的數(shù)據(jù)對(duì)item進(jìn)行建模。 我們需要從weather.sina.com.cn中獲取當(dāng)前城市名,后續(xù)9天的日期,天氣描述和溫度等信息。對(duì)此,在item中定義相應(yīng)的字段。編輯 weather 目錄中的 items.py 文件:

    # -*- coding: utf-8 -*-# Define here the models for your scraped items # # See documentation in: # http://doc.scrapy.org/en/latest/topics/items.html import scrapy class WeatherItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() # demo 1 city = scrapy.Field() date = scrapy.Field() dayDesc = scrapy.Field() dayTemp = scrapy.Field() pass

    3.4. 編寫獲取天氣數(shù)據(jù)的爬蟲(Spider)

    Spider是用戶編寫用于從單個(gè)網(wǎng)站(或者一些網(wǎng)站)爬取數(shù)據(jù)的類。

    其包含了一個(gè)用于下載的初始URL如何跟進(jìn)網(wǎng)頁(yè)中的鏈接以及如何分析頁(yè)面中的內(nèi)容提取生成 item 的方法。

    為了創(chuàng)建一個(gè)Spider,必須繼承 scrapy.Spider 類, 且定義以下三個(gè)屬性:

    • name: 用于區(qū)別Spider。該名字必須是唯一的,您不可以為不同的Spider設(shè)定相同的名字。

    • start_urls: 包含了Spider在啟動(dòng)時(shí)進(jìn)行爬取的url列表。因此,第一個(gè)被獲取到的頁(yè)面將是其中之一。后續(xù)的URL則從初始的URL獲取到的數(shù)據(jù)中提取。

    • parse() 是spider的一個(gè)方法。 被調(diào)用時(shí),每個(gè)初始URL完成下載后生成的 Response 對(duì)象將會(huì)作為唯一的參數(shù)傳遞給該函數(shù)。 該方法負(fù)責(zé)解析返回的數(shù)據(jù)(response data),提取數(shù)據(jù)(生成item)以及生成需要進(jìn)一步處理的URL的 Request 對(duì)象。

    我們通過(guò)瀏覽器的查看源碼工具先來(lái)分析一下需要獲取的數(shù)據(jù)網(wǎng)源代碼:

    <h4 class="slider_ct_name" id="slider_ct_name">武漢</h4> ... <div class="blk_fc_c0_scroll" id="blk_fc_c0_scroll" style="width: 1700px;"> <div class="blk_fc_c0_i"> <p class="wt_fc_c0_i_date">01-28</p> <p class="wt_fc_c0_i_day wt_fc_c0_i_today">今天</p> <p class="wt_fc_c0_i_icons clearfix"> <img class="icons0_wt png24" src="http://www.sinaimg.cn/dy/weather/main/index14/007/icons_42_yl/w_04_27_00.png" alt="雨夾雪" title="雨夾雪"> <img class="icons0_wt png24" src="http://www.sinaimg.cn/dy/weather/main/index14/007/icons_42_yl/w_04_29_01.png" alt="中雪" title="中雪"> </p> <p class="wt_fc_c0_i_times"> <span class="wt_fc_c0_i_time">白天</span> <span class="wt_fc_c0_i_time">夜間</span> </p> <p class="wt_fc_c0_i_temp">1°C / -2°C</p> <p class="wt_fc_c0_i_tip">北風(fēng) 3~4級(jí)</p> <p class="wt_fc_c0_i_tip">無(wú)持續(xù)風(fēng)向 小于3級(jí)</p> </div> <div class="blk_fc_c0_i"> <p class="wt_fc_c0_i_date">01-29</p> <p class="wt_fc_c0_i_day ">星期四</p> <p class="wt_fc_c0_i_icons clearfix"> <img class="icons0_wt png24" src="http://www.sinaimg.cn/dy/weather/main/index14/007/icons_42_yl/w_04_29_00.png" alt="中雪" title="中雪"> <img class="icons0_wt png24" src="http://www.sinaimg.cn/dy/weather/main/index14/007/icons_42_yl/w_07_25_01.png" alt="陰" title="陰"> </p> <p class="wt_fc_c0_i_times"> <span class="wt_fc_c0_i_time">白天</span> <span class="wt_fc_c0_i_time">夜間</span> </p> <p class="wt_fc_c0_i_temp">1°C / -2°C</p> <p class="wt_fc_c0_i_tip">無(wú)持續(xù)風(fēng)向 小于3級(jí)</p> </div> ... </div>

    我們可以看到:

    • 城市名可以通過(guò)獲取id為slider_ct_name的h4元素獲取
    • 日期可以通過(guò)獲取id為blk_fc_c0_scroll下的class為wt_fc_c0_i_date的p元素獲取
    • 天氣描述可以通過(guò)獲取id為blk_fc_c0_scroll下的class為icons0_wt的img元素獲取
    • 溫度可以通過(guò)獲取id為blk_fc_c0_scroll下的class為wt_fc_c0_i_temp的p元素獲取

    因此,我們的Spider代碼如下,保存在 weather/spiders 目錄下的 localweather.py 文件中:

    # -*- coding: utf-8 -*- import scrapy from weather.items import WeatherItemclass WeatherSpider(scrapy.Spider): name = "myweather" allowed_domains = ["sina.com.cn"] start_urls = ['http://weather.sina.com.cn'] def parse(self, response): item = WeatherItem() #把WeatheItem()實(shí)例化成item對(duì)象 item['city'] = response.xpath('//*[@id="slider_ct_name"]/text()').extract()#//*:選取文檔中的所有元素。@:選擇屬性 /:從節(jié)點(diǎn)選取 。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

    代碼中的xpath和css后面括號(hào)的內(nèi)容為選擇器,關(guān)于xpath和css選擇器的內(nèi)容可參考官方教程:http://doc.scrapy.org/en/0.24/topics/selectors.html

    3.5. 運(yùn)行爬蟲,對(duì)數(shù)據(jù)進(jìn)行驗(yàn)證

    到這里為止,我們需要驗(yàn)證一下爬蟲是否能正常工作(即能否取到我們想要的數(shù)據(jù)),驗(yàn)證的方法就是在命令行(重要:在項(xiàng)目的scrapy.cfg文件同級(jí)目錄運(yùn)行命令,下同)中運(yùn)行下面的代碼:

    $ scrapy crawl myweather -o wea.json

    這行命令的意思是,運(yùn)行名字為 myweather 的爬蟲(我們?cè)谏弦徊街卸x的),然后把結(jié)果以json格式保存在wea.json文件中。命令運(yùn)行結(jié)果如下:

    然后,我們查看當(dāng)前目錄下的wea.json文件,正常情況下效果如下:

    我們看到,wea.json中已經(jīng)有數(shù)據(jù)了,只是數(shù)據(jù)是以u(píng)nicode方式編碼的

    3.6. 保存爬取到的數(shù)據(jù)

    上面只是把數(shù)據(jù)保存在json文件中了,如果我們想自己保存在文件或數(shù)據(jù)庫(kù)中,如何操作呢?

    這里就要用到 Item Pipeline 了,那么 Item Pipeline 是什么呢?

    當(dāng)Item在Spider中被收集之后,它將會(huì)被傳遞到Item Pipeline中,一些組件會(huì)按照一定的順序執(zhí)行對(duì)Item的處理。

    每個(gè)item pipeline組件(有時(shí)稱之為“Item Pipeline”)是實(shí)現(xiàn)了簡(jiǎn)單方法的Python類。他們接收到Item并通過(guò)它執(zhí)行一些行為,同時(shí)也決定此Item是否繼續(xù)通過(guò)pipeline,或是被丟棄而不再進(jìn)行處理。

    item pipeline的典型應(yīng)用有:

    • 清理HTML數(shù)據(jù)
    • 驗(yàn)證爬取的數(shù)據(jù)(檢查item包含某些字段)
    • 查重(并丟棄)
    • 將爬取結(jié)果保存到文件或數(shù)據(jù)庫(kù)中

    每個(gè)item pipeline組件都需要調(diào)用 process_item 方法,這個(gè)方法必須返回一個(gè) Item (或任何繼承類)對(duì)象, 或是拋出 DropItem異常,被丟棄的item將不會(huì)被之后的pipeline組件所處理。

    我們這里把數(shù)據(jù)轉(zhuǎn)碼后保存在 wea.txt 文本中。

    pipelines.py文件在創(chuàng)建項(xiàng)目時(shí)已經(jīng)自動(dòng)被創(chuàng)建好了,我們?cè)谄渲屑由媳4娴轿募拇a:

    # -*- coding: utf-8 -*-# Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html class WeatherPipeline(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

    代碼比較簡(jiǎn)單,都是python比較基礎(chǔ)的語(yǔ)法,如果您感覺(jué)比較吃力,建議先去學(xué)一下python基礎(chǔ)課。

    3.7. 把 ITEM_PIPELINES 添加到設(shè)置中

    寫好ITEM_PIPELINES后,還有很重要的一步,就是把 ITEM_PIPELINES 添加到設(shè)置文件 settings.py 中。

    ITEM_PIPELINES = {'weather.pipelines.WeatherPipeline': 1 }

    另外,有些網(wǎng)站對(duì)網(wǎng)絡(luò)爬蟲進(jìn)行了阻止(注:本項(xiàng)目?jī)H從技術(shù)角度處理此問(wèn)題,個(gè)人強(qiáng)烈不建議您用爬蟲爬取有版權(quán)信息的數(shù)據(jù)),我們可以在設(shè)置中修改一下爬蟲的 USER_AGENT 和 Referer 信息,增加爬蟲請(qǐng)求的時(shí)間間隔。

    整個(gè) settings.py 文件內(nèi)容如下:

    # -*- coding: utf-8 -*-# Scrapy settings for weather project # # For simplicity, this file contains only the most important settings by # default. All the other settings are documented here: # # http://doc.scrapy.org/en/latest/topics/settings.html # BOT_NAME = 'Googlebot' SPIDER_MODULES = ['weather.spiders'] NEWSPIDER_MODULE = 'weather.spiders' # Crawl responsibly by identifying yourself (and your website) on the user-agent #USER_AGENT = 'weather (+http://www.yourdomain.com)' USER_AGENT = 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36' DEFAULT_REQUEST_HEADERS = { 'Referer': 'http://www.weibo.com' } ITEM_PIPELINES = { 'weather.pipelines.WeatherPipeline': 1 } DOWNLOAD_DELAY = 0.5

    到現(xiàn)在為止,代碼主要部分已經(jīng)寫完了。

    3.8. 運(yùn)行爬蟲

    在項(xiàng)目的scrapy.cfg同級(jí)目錄下用下面的命令運(yùn)行爬蟲:

    $ scrapy crawl myweather

    正常情況下,效果如下:

    然后,在當(dāng)前目錄下會(huì)多一個(gè) wea.txt 文件,內(nèi)容如下:

    到此我們基于scrapy的天氣數(shù)據(jù)采集就完成了。

    四、FAQ

    4.1. 結(jié)果只出現(xiàn)城市?

    scrapy內(nèi)置的html解析是基于lxml庫(kù)的,這個(gè)庫(kù)對(duì)html的解析的容錯(cuò)性不是很好,通過(guò)檢查虛擬機(jī)中獲取到的網(wǎng)頁(yè)源碼,發(fā)現(xiàn)有部分標(biāo)簽是不匹配的(地區(qū)和瀏覽器不同取到的源碼可能不同),檢查結(jié)果如圖:

    所以導(dǎo)致在spider中取到的日期數(shù)據(jù)(item['date'])為空,然后在pilepine代碼中做zip操作后,整個(gè) weaitem 為空,所以最終只有城市數(shù)據(jù)了。

    既然如此,我們換個(gè)html代碼解析器就可以了,這里建議用 BeautifulSoup (官網(wǎng):http://www.crummy.com/software/BeautifulSoup/bs4/doc/index.html?),這個(gè)解析器有比較好的容錯(cuò)能力,具體用法可以參考上面的文檔。

    BeautifulSoup安裝:

    #下載BeautifulSoup $ wget http://labfile.oss.aliyuncs.com/beautifulsoup4-4.3.2.tar.gz #解壓 $ tar -zxvf beautifulsoup4-4.3.2.tar.gz #安裝 $ cd beautifulsoup4-4.3.2 $ sudo python setup.py install

    安裝成功后,優(yōu)化WeatherSpider代碼,改進(jìn)后的代碼如下:

    # -*- coding: utf-8 -*- import scrapy from bs4 import BeautifulSoup from weather.items import WeatherItem class WeatherSpider(scrapy.Spider): name = "myweather" 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 = WeatherItem() 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

    然后再次運(yùn)行爬蟲:

    $ scrapy crawl myweather

    然后查看 wea.txt,數(shù)據(jù)如下:

    4.2. 只取到了9天的數(shù)據(jù)?

    如果是晚上運(yùn)行爬蟲,當(dāng)天的白天天氣是沒(méi)有的(已經(jīng)過(guò)去了),針對(duì)這部分建議自己優(yōu)化。

    五、實(shí)驗(yàn)代碼

    本實(shí)驗(yàn)的代碼可以通過(guò)下面這個(gè)鏈接獲取:

    http://git.shiyanlou.com/shiyanlou/scrapy-weather

    總結(jié)

    以上是生活随笔為你收集整理的基于scrapy爬虫的天气数据采集(python)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。