+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2020-03(61)

2020-04(50)

2020-05(20)

2020-06(45)

2020-07(18)

爬虫微博 Django(3.0) Scrapy Celery Supervisor

发布于2020-05-26 23:22     阅读(457)     评论(0)     点赞(27)     收藏(4)


  1. 搭建Django Server,用Django(Version 3.0)创建一个app,作为爬虫的入口;
    项目结构图
    在这里插入图片描述
  2. 用Django的Model创建数据库模型,数据库用的是Mysql;
  3. 跟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跳转

  1. 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)
  1. 实际爬虫期间,总是报数据连接数量过多(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()
  1. 在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()
  1. Django调用Scrapy,需要在Django创建的APP里用celery创建一个job,在job里调用run_spider.spider_weibo(’****’);
  2. 最后用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
  1. 这里我使用了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

10.用Supervisor启动Django,如果把Debug设成False ,会出现找不到静态文件的问题,所以我用Apache启动Django(可以参考我的另一篇文章Apache部署django),Supervisor负责启动Celery.

  1. 这里我做了一个前端页面来显示爬虫微博的结果,每隔五分钟爬一次微博,抓取特定用户当天发的微博,想观察效果可以关注公众号 ----岛城窝窝 ,回复 微博 查看页面
    在这里插入图片描述
    在这里插入图片描述
  2. dd

原文链接:https://blog.csdn.net/letunihao/article/details/106315679



所属网站分类: 技术文章 > 博客

作者:我Lovepython

链接: https://www.pythonheidong.com/blog/article/393454/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

27 0
收藏该文
已收藏

评论内容:(最多支持255个字符)