问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

scrapy异步爬虫运行正常为什么没有将数据存储到mysql中去

发布网友 发布时间:2022-04-07 21:55

我来回答

2个回答

懂视网 时间:2022-04-08 02:16

2.7.10 (default, Jun 5 2015, 17:56:24) [GCC 4.4.4 20100726 (Red Hat 4.4.4-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import MySQLdb Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named MySQLdb

 

  如果出现:ImportError: No module named MySQLdb则说明python尚未支持mysql,需要手工安装,请参考步骤2;如果没有报错,请调到步骤3

  2、python安装mysql支持

[root@bogon ~]# pip install mysql-python
Collecting mysql-python
 Downloading MySQL-python-1.2.5.zip (108kB)
 100% |████████████████████████████████| 110kB 115kB/s 
Building wheels for collected packages: mysql-python
 Running setup.py bdist_wheel for mysql-python
 Stored in directory: /root/.cache/pip/wheels/8c/0d/11/d654cad764b92636ce047897dd2b9e1b0cd76c22f813c5851a
Successfully built mysql-python
Installing collected packages: mysql-python
Successfully installed mysql-python-1.2.5

 

  安装完以后再次运行步骤1,检查python是否已经支持mysql

  如果还有问题您可以尝试:LC_ALL=C pip install mysql-python
  如果依然报错:error: Python.h: No such file or directory
  您可以尝试先安装python-devel:

yum install python-devel

 

  3、创建数据库和表

CREATE DATABASE cnblogsdb DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE TABLE `cnblogsinfo` (
 `linkmd5id` char(32) NOT NULL COMMENT ‘url md5编码id‘,
 `title` text COMMENT ‘标题‘,
 `description` text COMMENT ‘描述‘,
 `link` text COMMENT ‘url链接‘,
 `listUrl` text COMMENT ‘分页url链接‘,
 `updated` datetime DEFAULT NULL COMMENT ‘最后更新时间‘,
 PRIMARY KEY (`linkmd5id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

 

   注意:

    a)、创建数据库的时候加上DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci,这样才不至于出现乱码。我就因为这个问题折腾了很久。

    b)、数据库表的编码为utf8

  4、设置mysql配置信息

  根据前面的文章(scrapy爬虫成长日记之创建工程-抽取数据-保存为json格式的数据)我们可以知道,最终scrapy是通过pipelines.py对抓取的结果进行处理的。很显然要保存到mysql数据库中的话,修改pipelines.py这个文件是在所难免的了。然而在进行mysql操作的时候,我们需要先连上数据库,这时候就设计到数据库连接字符串的问题了。我们可以直接写死在pipelines.py文件中,但是这样又不利于程序的维护,因此我们可以考虑将配置信息写在项目的配置文件settings.py中。

  settings.py中添加如下配置项

# start MySQL database configure setting
MYSQL_HOST = ‘localhost‘
MYSQL_DBNAME = ‘cnblogsdb‘
MYSQL_USER = ‘root‘
MYSQL_PASSWD = ‘root‘
# end of MySQL database configure setting

   5、修改pipelines.py

  修改完的结果如下,需要注意的pipelines.py中定义了两个类。JsonWithEncodingCnblogsPipeline是写入json文件用的,而MySQLStoreCnblogsPipeline(需要记住,后面会用到哦!)才是写入数据库用的。

  MySQLStoreCnblogsPipeline类做的主要功能有

    a)、读取数据库配置文件,并生成数据库实例,主要通过类方法from_settings实现,

    b)、如果url不存在则直接写入,如果url存在则更新,通过自定义的方法_do_upinsert实现,

    c)、确保url唯一性的md5函数_get_linkmd5id 。

[root@bogon cnblogs]# more pipelines.py
# -*- 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

from scrapy import signals
import json
import codecs
from twisted.enterprise import adbapi
from datetime import datetime
from hashlib import md5
import MySQLdb
import MySQLdb.cursors

class JsonWithEncodingCnblogsPipeline(object):
 def __init__(self):
 self.file = codecs.open(‘cnblogs.json‘, ‘w‘, encoding=‘utf-8‘)
 def process_item(self, item, spider):
 line = json.dumps(dict(item), ensure_ascii=False) + "
"
 self.file.write(line)
 return item
 def spider_closed(self, spider):
 self.file.close()

class MySQLStoreCnblogsPipeline(object):
 def __init__(self, dbpool):
 self.dbpool = dbpool
 
 @classmethod
 def from_settings(cls, settings):
 dbargs = dict(
  host=settings[‘MYSQL_HOST‘],
  db=settings[‘MYSQL_DBNAME‘],
  user=settings[‘MYSQL_USER‘],
  passwd=settings[‘MYSQL_PASSWD‘],
  charset=‘utf8‘,
  cursorclass = MySQLdb.cursors.DictCursor,
  use_unicode= True,
 )
 dbpool = adbapi.ConnectionPool(‘MySQLdb‘, **dbargs)
 return cls(dbpool)

 #pipeline默认调用
 def process_item(self, item, spider):
 d = self.dbpool.runInteraction(self._do_upinsert, item, spider)
 d.addErrback(self._handle_error, item, spider)
 d.addBoth(lambda _: item)
 return d
 #将每行更新或写入数据库中
 def _do_upinsert(self, conn, item, spider):
 linkmd5id = self._get_linkmd5id(item)
 #print linkmd5id
 now = datetime.utcnow().replace(microsecond=0).isoformat(‘ ‘)
 conn.execute("""
  select 1 from cnblogsinfo where linkmd5id = %s
 """, (linkmd5id, ))
 ret = conn.fetchone()

 if ret:
  conn.execute("""
  update cnblogsinfo set title = %s, description = %s, link = %s, listUrl = %s, updated = %s where linkmd5id = %s
  """, (item[‘title‘], item[‘desc‘], item[‘link‘], item[‘listUrl‘], now, linkmd5id))
  #print """
  # update cnblogsinfo set title = %s, description = %s, link = %s, listUrl = %s, updated = %s where linkmd5id = %s
  #""", (item[‘title‘], item[‘desc‘], item[‘link‘], item[‘listUrl‘], now, linkmd5id)
 else:
  conn.execute("""
  insert into cnblogsinfo(linkmd5id, title, description, link, listUrl, updated) 
  values(%s, %s, %s, %s, %s, %s)
  """, (linkmd5id, item[‘title‘], item[‘desc‘], item[‘link‘], item[‘listUrl‘], now))
  #print """
  # insert into cnblogsinfo(linkmd5id, title, description, link, listUrl, updated)
  # values(%s, %s, %s, %s, %s, %s)
  #""", (linkmd5id, item[‘title‘], item[‘desc‘], item[‘link‘], item[‘listUrl‘], now)
 #获取url的md5编码
 def _get_linkmd5id(self, item):
 #url进行md5处理,为避免重复采集设计
 return md5(item[‘link‘]).hexdigest()
 #异常处理
 def _handle_error(self, failue, item, spider):
 log.err(failure)

 

   6、启用MySQLStoreCnblogsPipeline类,让它工作起来

  修改setting.py配置文件,添加MySQLStoreCnblogsPipeline的支持

ITEM_PIPELINES = {
 ‘cnblogs.pipelines.JsonWithEncodingCnblogsPipeline‘: 300,
 ‘cnblogs.pipelines.MySQLStoreCnblogsPipeline‘: 300,
}

  至此,所有的需要修改的文件都修改好了,下面测试看结果如何。

  7、测试

[root@bogon cnblogs]# scrapy crawl CnblogsSpider

  查看数据库结果:

技术分享

  至此,scrapy抓取网页内容写入数据库的功能就已经实现了。然而这个爬虫的功能还太弱小了,最基本的文件下载、分布式抓取等都功能都还不具备;同时也试想一下现在很多网站的反爬虫抓取的,万一碰到这样的网站我们要怎么处理呢?接下来的一段时间里我们来逐一解决这些问题吧。随便畅想一下,如果爬虫足够强,内容足够多;我们是不是可以打造一个属于自己的垂直搜索引擎呢?想想就兴奋,尽情YY去吧!!!

  最后源码更新至此:https://github.com/jackgitgz/CnblogsSpider

 

scrapy爬虫成长日记之将抓取内容写入mysql数据库

标签:

热心网友 时间:2022-04-07 23:24

Scrapy依赖于twisted,所以如果Scrapy能用,twisted肯定是已经安装好了。
抓取到的数据,可以直接丢到MySQL,也可以用Django的ORM模型丢到MySQL,方便Django调用。方法也很简单,按数据库的语句来写就行了,在spiders目录里定义自己的爬虫时也可以写进去。
当然使用pipelines.py是更通用的方法,以后修改也更加方便。你的情况,应该是没有在Settings.py里定义pipelines,所以Scrapy不会去执行,就不会生成pyc文件了。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
电脑分辨率设置多少合适笔记本电脑分辨率多少最佳 各尺寸笔记本电脑的最佳分辨率 2022年高考480到510分能上山东科技大学吗 朋友借了我一万块钱,现在坐牢了怎么还钱? 天王星和海王星虽然看似一对姊妹星,但还是有区别 ...值得收藏吗?现在分别只都多少钱,照片上有一个铜币的 谁能告诉我这是一枚什么样的铜币,值不值钱? 有谁知道这铜币值不值钱,懂家告诉我一下!谢谢 有谁知道这个铜钱的来历 可以进行异地公积金贷款吗 嵌入式电蒸箱好用吗? 嵌入式蒸箱好用吗?有啥不一样的? 蒸箱买嵌入式的还是台式的好?嵌入式的好安装吗? 电蒸箱台式与嵌入式的区别 方太蒸箱全都是嵌入式的吗? 开水烫伤起水泡怎么办 急!!! 嵌入式蒸箱与一般蒸箱区别 烤蒸微一体机安装全嵌好还是半嵌好? 嵌入式蒸烤箱和嵌入式微蒸烤箱有什么区别?那种更实用? 06年的车验车都需验什么, 开水烫出水泡怎样处理 被开水烫出水泡该怎么办?拜托了各位 谢谢 06年10月的车审到几月 06年的车一年审几次? 2006年的车现在一年一审吗? 雪佛兰乐驰06款怎么样车子年检好不好过 鱼香茄子怎么做简单又好吃? 2006年的车还能年审吗? 听人家说06年的不给审车 06年的车是不是汽车性能达标就能通过年审 马云发这种10亿红包大错特错了。就是一阵子而已,你不可能常年都发红包。要是我,我就出一个规矩 马云的10亿红包怎么越领越少呢,网友:太扎心 三羧酸循环的生理意义有哪些 那些打着瓜分20多亿的app,实际上到手能分到多少钱? 柠檬酸循环的生理意义体现在哪些方面 生化 蛋氨酸循环的生理意义,鸟氨酸循环的生理意义,三羧酸循环的生理意义,急,11月7号考试,谢谢。 三羧酸循环途径及意义? 为什么马云会公开认为马化腾的微信红包杀伤力巨大 什么是三羧酸循环?有什么特点及生物学意义 三羧酸循环的原理是什么 1.简述呼吸的概念、基本环节及生理意义 柠檬酸-丙酮酸循环的意义 三羧酸循环为什么是两用循环? 简述三羧酸循环及磷酸戊糖途径的生理 &#x273F;欢天喜地七仙女续集故事 求《长刀无痕》的后续 有没有看过啊 主人公叫赵烈 不愿屈法的兰陵公主的故事有哪些? 锦绣未央大结局剧情介绍 锦绣未央有续集第二季吗 《网球王子》的结局是什么? 世界上最短的科幻小说续写