資料視覺化 三步走(一):資料採集與儲存,利用python爬蟲框架scrapy爬取網路資料並存儲
阿新 • • 發佈:2019-01-10
前言
最近在研究python爬蟲,突然想寫部落格了,那就寫點東西吧。給自己定個小目標,做一個完整的簡單的資料視覺化的小專案,把整個相關技術鏈串聯起來,目的就是為了能夠對這塊有個系統的認識,具體設計思路如下:
1. 利用python爬蟲框架scrapy爬取網路資料並存儲到mysql中; 2. 利用springboot mybatis 作為web後臺服務; 3. 利用thymeleaf模板引擎 +echarts完成資料視覺化。
本章節完成第1點
1.Windows下搭建python環境
下載python3.6.4並安裝,注意:為了方便,一定要安裝pip模組和加入環境變數:
命令列執行python檢視是否安裝成功:
2.利用virtualenv建立虛擬環境,並安裝scrapy框架
- 安裝virtualenv: pip install virtualenv
- 新建資料夾PythonENV(自己隨便建,虛擬環境目錄),用於建立虛擬環境
- 建立虛擬環境env22:命令列cd 到PythonENV下,執行命令virtualenv env22
- 啟用env22:進入到env22\Scripts\下執行命令activate
- 如上圖,啟用後出現(env22)的字首,說明目前已經啟用成功並處於虛擬環境env22下,接下來我們就要在虛擬環境env22中安裝scrapy了,執行命令:pip install Scrapy
這裡遇到個問題:
安裝win32api模組:pip install pywin32
還需要將如下DLL拷貝到System32下:
- 建立Scrapy專案:Scrapy startproject mydemo
將建立好的專案匯入pycharm,結構如下:
至此,環境搭建和scrapy專案架構基本就完成了!
3. 編寫spider爬蟲,爬取豆瓣資料
1.items.py中定義豆瓣物件類,用於資料抽象封裝:
class DouBanItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
movie_title = scrapy.Field()
movie_score = scrapy.Field()
movie_eval_num = scrapy.Field()
movie_quote = scrapy.Field()
2.編寫spider,用於爬取豆瓣資料:
# encoding:utf-8
from scrapy.http import Request
from scrapy.spiders import CrawlSpider, Rule
from scrapy.selector import Selector
from mydemo.items import DouBanItem
class DouBanSpider(CrawlSpider):
name = "douban"
allowed_domains = ["movie.douban.com"]
start_urls = ["https://movie.douban.com/top250"]
#
# rules = (
# # 將所有符合正則表示式的url加入到抓取列表中
# Rule(LinkExtractor(allow=(r'https://movie\.douban\.com/top250\?start=\d+&filter=&type=',))),
# # 將所有符合正則表示式的url請求後下載網頁程式碼, 形成response後呼叫自定義回撥函式
# # 其實就是列表頁每一部電影的詳情頁面
# Rule(LinkExtractor(allow=(r'https://movie\.douban\.com/subject/\d+',)), callback='parse_page', follow=True),
# )
def parse(self, response):
doubanItem = DouBanItem()
selector = Selector(response)
movies = selector.xpath('//ol[@class="grid_view"]/li')
for m in movies:
# 電影名稱
doubanItem['movie_title'] = m.xpath('div/div[2]/div[1]/a/span[1]/text()').extract()[0]
# 電影評分
doubanItem['movie_score'] = m.xpath('div/div[2]/div[2]/div/span[2]/text()').extract()[0]
# 電影評價人數
doubanItem['movie_eval_num'] = m.xpath('div/div[2]/div[2]/div/span[4]/text()').extract()[0][:-3]
# movie_eval_num = re.findall(r'\d+', movie_eval)[-1] # 用切片也可以
# 電影短評 可能為空,發現不加[0] 也可以
movie_quote = m.xpath('div/div[2]/div[2]/p[2]/span/text()')[0]
if movie_quote:
doubanItem['movie_quote'] = movie_quote.extract()
else:
doubanItem['movie_quote'] = ''
yield doubanItem
for p in range(9): # 第2頁到第10頁
url_ = "https://movie.douban.com/top250?start={}&filter=".format(str((p+1)*25))
yield Request(url_, self.parse)
3.修改配置檔案settings.py,增加user_agent,禁用robot協議,以防止被禁
# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = ['Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240']
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
4.資料儲存
1.設定mysql資料來源(這是我本地的mysql):
# db configure
MYSQL_HOST = 'localhost'
MYSQL_DBNAME = 'python'
MYSQL_USER = 'root'
MYSQL_PASSWD = 'root'
2.編寫pipeline,用於處理爬取後返回的資料:
# -*- coding: utf-8 -*-
# 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
from logging import log
import pymysql
from mydemo import settings
class MySqlPipeline(object):
# 初始化資料庫
def __init__(self):
self.connect = pymysql.connect(
host=settings.MYSQL_HOST,
db=settings.MYSQL_DBNAME,
user=settings.MYSQL_USER,
passwd=settings.MYSQL_PASSWD,
charset='utf8',
use_unicode=True
)
# 通過cursor執行增刪查改
self.cursor = self.connect.cursor()
# 處理返回的item資料
def process_item(self, item, spider):
try:
# 增加查重處理
self.cursor.execute(
"""select * from t_movie where title = %s""",
item['movie_title'])
# 是否有重複資料
repetition = self.cursor.fetchone()
if repetition:
pass
else:
# 插入資料
self.cursor.execute(
"""insert into t_movie (title,score,eval_num,m_quote)
values (%s, %s, %s, %s)""",
(item['movie_title'],
item['movie_score'],
item['movie_eval_num'],
item['movie_quote']))
# 提交sql語句
self.connect.commit()
except Exception as error:
# 出現錯誤時列印錯誤日誌
log(error)
return item
3.終端執行爬蟲,命令:scrapy crawl douban
4.檢視mysql資料庫,資料已經儲存成功: