python爬蟲十一:scrapy框架爬取天氣,存入資料庫
阿新 • • 發佈:2019-01-25
小白學習:
轉:https://zhuanlan.zhihu.com/p/26885412
1.cmd下
scrapy startproject 專案名
2.我一般都是在pycharm中編寫程式碼,所以我會在idea中引入專案,這裡不知道如何在pycharm中下載scrapy模組的童鞋,可看我前面的部落格:
進入檔案下
scrapy genspider 檔名 爬取的網站
scrapy genspider SZtianqi suzhou.tianqi.com
會在資料夾下生成一個SZtianqi的檔案3.編寫items.py這個檔案,是我們想要封裝的名字,在這裡面定義
# -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # https://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() date=scrapy.Field();#時間 week=scrapy.Field();#日期 img=scrapy.Field();#照片地址 temperature=scrapy.Field();#溫度 weather=scrapy.Field();#天氣 wind=scrapy.Field();#風速
4.編寫SZtianqi.py:作用的從網站上抓取資料,這裡和之前的get_html的方法一致,將網頁的資料篩取存入item中
# -*- coding: utf-8 -*- import scrapy from weather.items import WeatherItem class SztianqiSpider(scrapy.Spider): name = "SZtianqi" # 我們修改一下host,使得Scrapy可以爬取除了蘇州之外的天氣 allowed_domains = ["tianqi.com"] # 建立需要爬取資訊的url列表 start_urls = [] # 需要爬的城市名稱 citys = ['nanjing', 'suzhou', 'shanghai'] # 用一個很簡答的迴圈來生成需要爬的連結: for city in citys: start_urls.append('http://' + city + '.tianqi.com') def parse(self, response): ''' 篩選資訊的函式: date = 今日日期 week = 星期幾 img = 表示天氣的圖示 temperature = 當天的溫度 weather = 當天的天氣 wind = 當天的風向 ''' # 先建立一個列表,用來儲存每天的資訊 items = [] # 找到包裹著每天天氣資訊的div sixday = response.xpath('//div[@class="tqshow1"]') # 迴圈篩選出每天的資訊: for day in sixday: # 先申請一個weatheritem 的型別來儲存結果 item = WeatherItem() # 觀察網頁,知道h3標籤下的不單單是一行str,我們用trick的方式將它連線起來 date = '' for datetitle in day.xpath('./h3//text()').extract(): date += datetitle item['date'] = date item['week'] = day.xpath('./p//text()').extract()[0] item['img'] = day.xpath( './ul/li[@class="tqpng"]/img/@src').extract()[0] tq = day.xpath('./ul/li[2]//text()').extract() # 我們用第二種取巧的方式,將tq裡找到的str連線 item['temperature'] = ''.join(tq) item['weather'] = day.xpath('./ul/li[3]/text()').extract()[0] item['wind'] = day.xpath('./ul/li[4]/text()').extract()[0] items.append(item) return items
這裡面的
from weather.items import WeatherItem
是引入items.py的一個類,用與封裝的
5.處理封裝好的item物件,編寫pipelins.py:作用的將資料存入本地或資料庫
# -*- coding: utf-8 -*- import os import requests import json import codecs import pymysql # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html ''' 我們知道,pipelines.py是用來處理收尾爬蟲抓到的資料的, 一般情況下,我們會將資料存到本地: 文字形式: 最基本的方式 json格式 :方便其他程式設計師呼叫 資料庫: 資料量多時 ''' #寫入txt檔案 class WeatherPipeline(object): def process_item(self, item, spider): ''' 處理每一個從SZtianqi傳過來的 item ''' #獲取當前的工作目錄 basc_dir=os.getcwd(); #把檔案儲存到data目錄下 filename=basc_dir+'\\weather\\data\\weather.txt' #已追加的方式開啟檔案並寫入對應的資訊 with open(filename,'a',encoding='utf-8') as f: f.write(item['date']+'\n') f.write(item['week']+'\n') f.write(item['temperature']+'\n') f.write(item['wind']+'\n') f.write(item['weather']+'\n') f.write(item['img']+'\n') #下載圖片 file_img=basc_dir+'\\weather\\data\\image\\'+item['date']+'.png' with open(file_img,'wb') as f: f.write(requests.get(item['img']).content) #print('aaaaaaaaaaaaaaaaaaaaaaaaa') return item #寫入json檔案 class W2json(object): def process_item(self, item, spider): #獲取本地檔案 basc_dir=os.getcwd(); json_dir=basc_dir+'\\weather\\data\\weather.json' # 開啟json檔案,向裡面以dumps的方式吸入資料 # 注意需要有一個引數ensure_ascii=False ,不然資料會直接為utf編碼的方式存入比如:“/xe15” with codecs.open(json_dir,'a',encoding='utf-8') as f: line=json.dumps(dict(item),ensure_ascii=False)+'\n' f.write(line) return item #將資料存入資料庫 class Rmysql(object): def process_item(self, item, spider): #抓取資料存入mysql #將資料從item中拿出來 date=item['date']; week=item['week']; img=item['img'] temperature=item['temperature'] weather=item['weather'] wind=item['wind'] #和本地的資料庫連線起來 connection=pymysql.connect( host='localhost', # 連線的是本地資料庫 user='root', # 自己的mysql使用者名稱 passwd='123456', # 自己的密碼 db='scrapyDB', # 資料庫的名字 charset='utf8mb4', # 預設的編碼方式: cursorclass=pymysql.cursors.DictCursor) #插庫 try: with connection.cursor() as cursor: #建立更新資料庫的sql sql="""INSERT INTO WEATHER(date,week,img,temperature,weather,wind) VALUES (%s, %s,%s,%s,%s,%s)""" #執行sql cursor.execute(sql,(date,week,img,temperature,weather,wind)) #提交插入資料 connection.commit() finally: #關閉資源 的第二個引數可以將sql預設語句補全,一般以元組的格式 connection.close() return item
6.在settings中,呼叫pipelines的方法
7.執行專案
scrapy crawl SZtianqi
在編寫程式碼是可一邊測試一邊編寫從終端看結果
資料庫結果