逆向爬虫14 Mongo入门

一、MongoDB和MySQL的区别

MongoDB 是一种 非关系型数据库,存放任意形式的 json 格式数据;而 MySQL 是一种 关系型数据库,只能存放事先定义好 字段 的表格数据。下面是 MongoDBMySQL 对数据叫法不同的比较。

MySQL MongoDB
数据库(文件夹) 数据库(文件夹)
表(文件,不同的表之间可以有关系) 集合(文件,不同的集合之间没有关系)
记录(表格的一行) 文档(一个json格式数据)

二、何时使用关系型?何时使用非关系型?

关系型数据库 比较合适用于需要对数据进行业务逻辑开发的场景,大量应用于Web全栈开发中,用户通过前端将信息提交给后端,后端再通过业务逻辑处理后,将需要存储的数据保存到 关系型数据库 中;当用户在前端申请查看信息后,后端从 关系型数据库 中读取数据,经业务逻辑处理后,发送给前端,再经过前端渲染后呈现在用户面前。在这个过程中,数据库中所存放的内容,严格的受到业务逻辑的控制,因此在创建数据库之前,就需要根据业务逻辑先确定每一张表的字段名,不同表之间的关系,这些关系确定好后就很少再会变动,除非业务逻辑需要。

非关系型数据库 相比于 关系型数据库 来说使用起来更为方便,即插即用。使用前无需事先确定字段,表与表关系等信息。数据格式只要满足 json 就可以存储。这对于需要存储大量不规则数据来说方便极了,爬虫所爬的每个网站的数据都是没有标准统一的,如果使用 关系型数据库,在数据入库之前,就需要针对每一个网站需要爬取的不同信息,新建一张表。而 非关系型数据库 则无需这步操作,获取到数据后整理成 json 格式后即可以插入到数据库,十分方便。

因此,在只需要保存数据,且无需对数据进行业务逻辑处理的业务场景下,使用 非关系型数据库 更为合适,这也是我们要学习 MongoDB 的原因。

三、MongoDB的简单使用(了解)

MongoDB的安装这里就不赘述了,网上到处都有。这里直接进入正题。

show dbs         显示所有数据库(简写)
show databases      显示所有数据库(全写)
db                  查看当前使用的数据库
use xxx             切换数据库
db.dropDatabase()   删除数据库
show collections    显示当前数据库中所有的集合
db.collection_name.insert({})   往集合中插入一条数据{}中放json格式数据,如果集合不存在则创建,且没有大小限制
db.createCollection(name, {options})    手动创建集合,可以增加options来限制集合,下面给个例子
db.createCollection("xxx_log", {capped:true, size:255})       capped:是否卷动, size:大小
上面这种创建方式特别适合用来存放日志类型的数据,当日志数据大于size大小后,会自动清除时间最早的数据,插入最新的数据
db.collection_name.isCapped()   判断集合是否有容量上限

四、MongoDB的增删改查

1. mongodb中常见的数据类型(了解)

Object ID: 主键ID
String: 字符串
Boolean: 布尔值
Integer: 数字
Double: 小数
Arrays: 数组
Object: 文档(关联其他对象) {sname: 李嘉诚, sage: 18, class: {cccc}}
Null: 空值
Timestamp: 时间戳
Date: 时间日期

2. mongodb添加数据

db.collection_name.insert({字段1:值1, 字段2:值2})
db.student.insert({name: '周杰伦', age: 18, hobby: ['哎哟,不错哦!', '耍酷']})

注意:如果集合不存在会自动创建

3. mongodb修改数据

3.1 update更新

db.collection_name.update({查询条件}, {待修改内容}, {multi: false, upsert: true})
multi 默认为false,只会修改一条数据
upsert 默认为true,待修改内容中如果存在新的数据则添加进去
db.student.update({name: '周杰伦'}, {$set: {title: '华语流行天王', age: 16}})

s e t 和 没 有 set和没有 set和没有set的区别:

​ $set只会修改当前给出的字段,其他内容保留

​ 没有$set只会保留当前给出字段,其他内容删除

multi如果为true,必须使用$set,否则报错。

3.2 保存(save,了解)

db.collection_name.save({待保存的数据})
db.student.save({name: '王力宏', age: 188})

相当于新增了一条王力宏数据,如果待保存数据中包含已经存在数据的’_id’信息,则相当于update功能

4. mongodb删除数据

4.1 remove()

db.collection_name.remove({条件}, {justOne: true|false})
db.student.remove({name: '王力宏'}, {justOne: true})

4.2 deleteOne()

db.collection_name.deleteOne({条件})
db.student.deleteOne({name: '蔡依林'})

4.3 deleteMany()

db.collection_name.deleteMany({条件})
db.student.deleteMany({type: '歌手'})

5. mongodb查询数据

准备数据:

db.student.insert([{name: "朱元璋", age:800, address:'安徽省凤阳', score: 160},{name: "朱棣", age:750, address:'江苏省南京市', score: 120},{name: "朱高炽", age:700, address:'北京紫禁城', score: 90},{name: "李嘉诚", age:38, address:'香港xxx街道', score: 70},{name: "麻花藤", age:28, address:'广东省xxx市', score: 80},{name: "大老王", age:33, address:'火星第一卫星', score: -60},{name: "咩咩", age:33, address:'开普勒225旁边的黑洞', score: -160}
])

5.1 普通查询

db.student.find()        查询所有
db.student.findOne()    查询一个
db.student.find({条件})  条件查询

5.2 比较运算

等于:默认是等于判断,$eq
小于:$lt (less than)
小于等于:$lte (less than equal)
大于:$gt (greater than)
大于等于:$gte (greater than equal)
不等于:$ne (not equal)
db.student.find({age:28})            // 查询年龄为28的学生
db.student.find({age:{$eq:28}})     // 查询年龄为28的学生
db.student.find({age:{$gt:28}})     // 查询年龄大于28的学生
db.student.find({age:{$gte:28}})    // 查询年龄大于等于28的学生
db.student.find({age:{$lt:38}})     // 查询年龄小于38的学生
db.student.find({age:{$lte:38}})    // 查询年龄小于等于38的学生
db.student.find({age:{$ne:38}})     // 查询年龄不等于38的学生

5.3 逻辑运算符

  1. and

    $and: [条件1,条件2,条件3]

查询年龄等于33,并且,名字是'大老王'的学生
db.student.find({$and: [{age: {$eq:33}}, {name: '大老王'}]})
  1. or

    $or: [条件1,条件2,条件3]

查询名字叫'李嘉诚',或者,年龄大于100岁的学生
db.student.find({$or: [{name: '李嘉诚'}, {age: {$gt: 100}}]})
  1. nor

    $nor: [条件1,条件2,条件3]

查询年龄不等于38,并且,名字不叫'朱元璋'的学生
db.student.find({$nor: [{age: {$lt:38}}, {name: '朱元璋'}]})

5.4 范围运算符

使用 i n , in, in,nin判断数据是否在某个数组内

查询年龄是28或38的学生
db.student.find({age: {$in: [28, 38]}})

5.5 正则表达式

使用$regex进行正则表达式匹配

查询地址是北京的学生信息
db.student.find({address: {$regex: '^北京'}})
db.student.find({address: /^北京/})

5.6 自定义查询 (了解)

mongo shell是一个js的执行环境

使用 $where 写一个函数,返回满足条件的数据

查询年龄大于38岁的学生信息
db.student.find({$where: function(){return this.age > 38}})

5.7 skip 和 limit

db.student.find().skip(3).limit(3)

跳过3个,提取3个,类似limit 3,3 可以用来做分页

5.8 投影

投影可以控制最终查询的结果(字段筛选)

查询所有学生的数据的姓名,年龄,分数,但不显示它们的_id
db.student.find({}, {_id: 0, name: 1, age: 1, score: 1})

需要看的字段给1

注意,除了_id外,0,1不能共存

5.9 排序

sort({字段:1, 字段:-1})

1表示升序

-1表示降序

将所有学生的成绩按照降序排列
db.student.find().sort({score:-1})

5.10 统计数量

count(条件) 查询数量

统计年龄为33的学生个数
db.student.count({age: 33})

五、pymongo的使用

1. 增删改查操作

from audioop import add
from pymongo import MongoClientdef get_db(database, user=None, pwd=None):client = MongoClient(host='localhost', port=27017)  # 默认端口号:27017# 如果有账号,则需要登录# admin = client['admin']# admin.authenticate(user, pwd)# 如果没有设置用户名密码,直接切换就可以了db = client[database]     # use hahareturn dbdef add_one(database, table, data):db = get_db(database)result = db[table].insert_one(data)return resultdef add_many(database, table, data_list):db = get_db(database)result = db[table].insert_many(data_list)return resultdef upd(database, table, condition, data):db = get_db(database)result = db[table].update_many(condition, {'$set': data})return resultdef delete(database, table, condition):db = get_db(database)result = db[table].delete_many(condition)return resultdef query(database, table, condition):db = get_db(database)result = db[table].find(condition)return list(result)if __name__ == '__main__':# 增加一条学生信息ret = add_one('haha', 'student', {'name': '周杰伦', 'age': 18, 'address': '元宇宙', 'score': '无穷大'})print(ret)# 增加多条学生信息data_list = [{'name': '蔡依林', 'age': 17, 'address': '元宇宙', 'score': '无穷大大'},{'name': '陈奕迅', 'age': 19, 'address': '元宇宙', 'score': '无穷小'},{'name': '张学友', 'age': 20, 'address': '元宇宙', 'score': '无穷小小'}]ret = add_many('haha', 'student', data_list)print(ret)# 修改学生信息ret = upd('haha', 'student', {"address": "元宇宙"}, {"score": 100})print(ret)# 删除学生信息ret = delete('haha', 'student', {"address": "元宇宙"})print(ret)# 查询年纪大于33岁的学生信息ret = query('haha', 'student', {"age": {"$gt": 33}})for r in ret:print(r)# 查询北京学生的信息ret = query('haha', 'student', {"address": {"$regex": "^北"}})for r in ret:print(r)

2. 抓取二手房信息

import requests
from lxml import etree
from mangodb import add_many
import pymysqldef get_page_source(url):resp = requests.get(url)page_source = resp.textreturn page_sourcedef parse(html):tree = etree.HTML(html)li_list = tree.xpath('//ul[@class="sellListContent"]/li')result = []for li in li_list:title = li.xpath('./div[1]/div[1]/a/text()')[0]address = ' '.join(li.xpath('./div[1]/div[2]/div/a/text()'))houseInfo = li.xpath('./div[1]/div[3]/div/text()')[0]starInfo = li.xpath('./div[1]/div[4]/text()')[0]tag = ' '.join(li.xpath('./div[1]/div[5]/span/text()'))total_price = li.xpath('./div[1]/div[6]/div[1]/span/text()')[0] + '万元'per_price = li.xpath('./div[1]/div[6]/div[2]/span/text()')[0]dic = {"title": title,"address": address,"houseInfo": houseInfo,"starInfo": starInfo,"tag": tag,"total_price": total_price,"per_price": per_price}result.append(dic)return resultdef save_to_mongo(data_list):add_many('ershoufang', 'ershoufang', data_list)print("一页保存完毕!")def save_to_mysql(data_list):try:conn = pymysql.connect(host='localhost',port=3306,user='root',  # The first four arguments is based on DB-API 2.0 recommendation.password="xxxxxx",database='spider')cursor = conn.cursor()sql = """insert into ershoufang(title, address, houseInfo, startInfo, tag, total_price, per_price) values(%s, %s, %s, %s, %s, %s, %s)"""lst = (tuple(dic.values()) for dic in data_list)cursor.executemany(sql, lst)conn.commit()print("一页保存完毕!")except:conn.rollback()finally:if cursor:cursor.close()if conn:conn.close()if __name__ == '__main__':for i in range(1, 31):url = "https://bj.lianjia.com/ershoufang/pg{i}/"page_source = get_page_source(url)data_list = parse(page_source)# save_to_mongo(data_list)save_to_mysql(data_list)

逆向爬虫14 Mongo入门相关推荐

  1. 逆向爬虫20 Scrapy-Splash入门

    逆向爬虫20 Scrapy-Splash入门 一. Splash 在学习Splash之前,先要明白为什么要学它,它能帮我们完成什么工作,什么情况下适合使用Splash? splash是一个可以动态渲染 ...

  2. 逆向爬虫18 Scrapy抓取全站数据和Redis入门

    逆向爬虫18 Scrapy抓取全站数据和Redis入门 一.全站数据抓取 1. 什么是抓取全站数据? 我们曾经在过猪八戒,图片之家,BOSS直聘等网站,利用网站官方提供的搜索功能,搜索指定关键词的内容 ...

  3. 逆向爬虫08 并发异步编程

    逆向爬虫08 并发异步编程 我将引用我最喜欢的路飞学城林海峰Egon老师的讲课方式来复习这一节的内容. 1. 什么是并发异步编程? 这一部分的内容来源于计算机操作系统,如果想要详细了解并发异步等概念, ...

  4. python数据分析案例2-1:Python练习-Python爬虫框架Scrapy入门与实践

    本文建立在学习完大壮老师视频Python最火爬虫框架Scrapy入门与实践,自己一步一步操作后做一个记录(建议跟我一样的新手都一步一步进行操作). 主要介绍: 1.scrapy框架简介.数据在框架内如 ...

  5. JSOUP 教程—— Java爬虫,简易入门,秒杀htmlparser

    转载自 JSOUP 教程-- Java爬虫,简易入门,秒杀htmlparser 关于爬虫,之前一直用做第一个站的时候,记得那时候写的 爬虫  是爬sina 的数据,用的就是 htmlparser  可 ...

  6. 一步一步学python爬虫_初学Python之爬虫的简单入门

    初学Python之爬虫的简单入门 一.什么是爬虫? 1.简单介绍爬虫 爬虫的全称为网络爬虫,简称爬虫,别名有网络机器人,网络蜘蛛等等. 网络爬虫是一种自动获取网页内容的程序,为搜索引擎提供了重要的数据 ...

  7. 互联网金融爬虫怎么写-第二课 雪球网股票爬虫(正则表达式入门)

    系列教程: 互联网金融爬虫怎么写-第一课 p2p网贷爬虫(XPath入门) 上一节课我们一起通过一个p2p网贷爬虫,深入了解了一下XPath以及其在最终实际使用中的写法.可以毫不夸张的说,对于写简单爬 ...

  8. Python爬虫开发从入门到实战

    Python爬虫开发从入门到实战(微课版) 第1章 绪论 爬虫的主要目的是获取网页内容并解析.只要能达到这个目的,用什么方法都没有问题. 关于获取网页,本书主要介绍了Python的两个第三方模块,一个 ...

  9. 逆向爬虫28 webpack扣代码

    逆向爬虫28 webpack扣取码 目标: 了解 js 模块化打包webpack代码的特点. 掌握扣取 webpack 代码的方法. 一. 模块化 webpack 代码特点 有的时候, 我们发现一些网 ...

最新文章

  1. *dev=filp-private_data;这一句的理解
  2. 关于VS2017中fopen、fscanf等函数无法使用的问题
  3. 21-break、continue、return语句理解
  4. MYSQL导出数据报错ERROR 1290 (HY000) 和 ERROR 1 (HY000)
  5. ffmpeg图片缩放
  6. 并发编程-concurrent指南-原子操作类-AtomicInteger
  7. jquery中如何获得$.ajax()事件返回的值
  8. mysql连表删除语句_MySQL中联表更新与删除的语法介绍
  9. 误删除MySQL数据库表的ibd文件怎么办
  10. 详解Vue中的自定义指令
  11. win7怎么修改计算机皮肤,鼠标指针怎么换?小编教你win7系统更换鼠标指针皮肤的方法...
  12. 首届中国云南普洱茶茶王获奖名单及常识
  13. IDEA启动显示 找不到应用程序
  14. 强大的图片预览组件Viewer.js
  15. Bean、BeanDefinition、BeanFactory、FactoryBean
  16. 从dom4j到JAXB
  17. 小记一次海量数据实时查询域名库设计(上)
  18. Android 10.0 ​默认允许未知来源权限安装
  19. 数据库第七周【第五章作业存储过程】
  20. 菜鸟也谈js(一)——ES6解构对象篇

热门文章

  1. 飞思卡尔16位单片机(十五)—— 如何批量烧写芯片
  2. GeoMesa 详细介绍
  3. Line营销机器人2019版
  4. java-不死神兔百钱百鸡
  5. connectbot 1.8.2 下载from github
  6. php 接收复杂json,php解析复杂json的实例 - 火车api的应用
  7. mysql5_7winx64,MySQL 5.7.30 Winx64 安装
  8. FreeSWITCH 智能呼叫流程设计
  9. 目标检测经典论文——Faster R-CNN论文翻译:Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Net
  10. 宜家订单JSON_怎么评价宜家(IKEA)?