- 搭建Django Server,用Django(Version 3.0)創建一個app,作爲爬蟲的入口;
- 用Django的Model創建數據庫模型,數據庫用的是Mysql;
- 跟Django 的app同目錄創建一個Scrapy項目,先單獨編寫爬蟲的代碼,讓爬蟲可以正常運行,爬蟲微博使用的是Cookie的方式,先從網頁瀏覽器中登錄微博,獲取Cookie,把Cookie放到Scrapy Settings.py 的DEFAULT_REQUEST_HEADERS裏
DEFAULT_REQUEST_HEADERS = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0',
'Cookie':'WEIBOCN_WM=******************************'
}
測試發現如果不使用Settings裏的Cookie,在spiders文件夾下的爬蟲文件 start_requests函數單獨定義Cookie不好使,登錄微博總是出現401跳轉
- Scrapy 項目下創建DBHelper類,用於保存爬蟲數據到數據庫
# -*- coding: utf-8 -*-
import pymysql
from twisted.enterprise import adbapi
from scrapy.utils.project import get_project_settings #導入seetings配置
import time
table_name = '**********'
class DBHelper():
'''這個類也是讀取settings中的配置,自行修改代碼進行操作'''
def __init__(self):
settings = get_project_settings() #獲取settings配置,設置需要的信息
dbparams = dict(
host=settings['MYSQL_HOST'], #讀取settings中的配置
db=settings['MYSQL_DBNAME'],
user=settings['MYSQL_USER'],
passwd=settings['MYSQL_PASSWD'],
charset='utf8', #編碼要加上,否則可能出現中文亂碼問題
cursorclass=pymysql.cursors.DictCursor,
use_unicode=False,
)
#**表示將字典擴展爲關鍵字參數,相當於host=xxx,db=yyy....
dbpool = adbapi.ConnectionPool('pymysql', **dbparams)
self.dbpool = dbpool
def connect(self):
return self.dbpool
def close(self):
self.dbpool.close()
#寫入數據庫
def insert(self, item):
sql = "insert into " + table_name + "(blog_short_name,weibo_id,weibo_url,created_at,like_num,repost_num,comment_num,content,user_id,tool,image_url,image_origin_url,video_url,origin_weibo,location_map_info,crawl_time,created_at_date) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
#調用插入的方法
query = self.dbpool.runInteraction(self._conditional_insert, sql, item)
#調用異常處理方法
query.addErrback(self._handle_error)
return item
#寫入數據庫中
def _conditional_insert(self, tx, sql, item):
# 抓取時間戳
item['crawl_time'] = time.strftime('%Y-%m-%d %H:%M:%S',
time.localtime(time.time()))
params = (item['blog_short_name'],item["_id"], item['weibo_url'], item['created_at'],
item['like_num'],item["repost_num"], item['comment_num'], item['content'],item['user_id'],item['tool'],item["image_url"],item["image_origin_url"], item['video_url'], item['origin_weibo'],item['location_map_info'], item['crawl_time'], item['created_at_date'])
if (item['created_at_date'] == str(time.strftime("%Y-%m-%d", time.localtime()))) :
# 判斷微博數據庫是否存在
query_sql = "select * from " + table_name + " where weibo_id = '" + item["_id"] + "'"
tx.execute(query_sql)
query_result = tx.fetchall()
if query_result:
print('微博數據庫已存在!!!')
else:
print('新微博')
tx.execute(sql, params)
else:
print('不是當天的微博')
#錯誤處理方法
def _handle_error(self, failue):
print(failue)
- 實際爬蟲期間,總是報數據連接數量過多(1040 - too many connections),發現爬蟲過程中沒有關閉數據庫連接,在pipelines.py文件中複寫close_spider函數,調用DBHelper的close方法,數據庫連接數量過多的問題就解決了;
class WeiBoPipeline(object):
# 連接數據庫
def __init__(self):
self.db = DBHelper()
def process_item(self, item, spider):
# 插入數據庫
self.db.insert(item)
return item
def close_spider(self,spider): #關閉蜘蛛
self.db.close()
- 在Scrapy的settings.py 同目錄下創建一個run_spider.py文件,這裏使用的是CrawlerRunner,而不是CrawlerProcess,因爲使用Process會出現ReactorNotRestartable錯誤
import os
import sys
from scrapy.crawler import CrawlerProcess
from scrapy.crawler import CrawlerRunner
from scrapy.utils.project import get_project_settings
from crochet import setup
def spider_weibo(mode):
setup()
settings = get_project_settings()
runner = CrawlerRunner(settings)
runner.crawl(*****, 'all')
runner.join()
- Django調用Scrapy,需要在Django創建的APP裏用celery創建一個job,在job裏調用run_spider.spider_weibo(’****’);
- 最後用supervisor進程管理,啓動Django,celery,這裏supervisor我用pip安裝的,安裝到了Django的venv中;
[program:supervisor_django]
command=/Project/weixin/venv/bin/python manage.py runserver 0.0.0.0:80
[program:supervisor_celery_worker]
command=/Project/weixin/venv/bin/celery -A djangoWeb worker -l info
[program:supervisor_celery_beat]
command=/Project/weixin/venv/bin/celery -A djangoWeb beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
- 這裏我使用了django-celery-beat後臺管理的頁面,添加定時任務,如果出現了時區的問題,可是在Django的settings文件裏添加
# 官方用來修復CELERY_ENABLE_UTC=False and USE_TZ = False 時時間比較錯誤的問題;
# 詳情見:https://github.com/celery/django-celery-beat/pull/216/files
DJANGO_CELERY_BEAT_TZ_AWARE = False
- 這裏我做了一個前端頁面來顯示爬蟲微博的結果,每隔五分鐘爬一次微博,抓取特定用戶當天發的微博,想觀察效果可以關注公衆號 ----島城窩窩 ,回覆 微博 查看頁面