准备系统地复习一遍爬虫,填填坑。
contents
一:数据库的使用(mongoDB)
1.什么是MongoDB?
MongoDB 是一款开源的文档数据库,并且是业内领先的 NoSQL 数据库,用 C++ 编写而成。
2.为什么要使用MongoDB数据库
MongoDB是非关系型数据库,MongoDB数据的储存形式和Python的字典非常的相似。
如下图所示:python爬虫系统学习一:数据库的使用,mongoDB
3.MongoDB 的安装
1)百度mongodb官网选择自己系统匹配的版本下载并安装
2)创建文件夹用来存放数据文件:D:\MongoDB\DB
3)在MongoDB的安装文件夹中,按住Shift键并点击鼠标右键,选择“在此处打开命令窗口”,然后输入以下代码启动MongoDB:
mongod.exe--dbpathD:\MongoDB\DB
4.图形化图形化管理工具-RoboMongo
简介:RoboMongo是一个跨平台的MongoDB管理工具。可以用来在图形界面中观察我们对MongoDB的修改是否生效。
安装以后,我们打开可以看到下图的栏目:
点击“Create”,如果MongoDB就在本地电脑上面运行,那就什么都不需要修改,直接点Save
回到图1的界面,点击“Connect”就可以联接MongoDB了。
二:python环境的安装
python安装
这里使用python2.7版本的环境
同样直接百度python官网下载自己系统对应版本的python解释器exe格式或msi格式都可以
注意:不要下载360软件管家提供的 python2.7.12rc1解释器此解释器无法使用pip安装第三方包
安装完成之后打开命令提示符 cmd 直接输入 python 如果安装成功则会出现如下提示
如果没有出现上图的提示则检查系统环境变量
参考 http://jingyan.baidu.com/article/48206aeafdcf2a216ad6b316.html
PyMongo 的简介及安装
1.什么是 PyMongo?
PyMongo模块是Python对MongoDB操作的接口包,代码主要实现对MongoDB的几种操作:增删改查以及排序等功能。
2.PyMongo 的安装
使用以下几种方法之一即可:
(1)直接使用pip 安装(推荐)
安装命令如下:
pip install pymongo
如果安装成功会显示pymongo包的版本号
(2)使用easy_install 安装
安装命令如下:
easy_install pymongo
由于众所周知的原因,pip 直接安装可能会遇到网络问题导致安装失败,因此,对于Windows下的同学,还可以访问:
http://www.lfd.uci.edu/~gohlke/pythonlibs/
在这个网站上找到pymongo,并下载whl包到本地,然后使用以下命令安装:
注意要下载与你python版本相符的pymongo包
pip install
下载下来的whl文件名
对于一些更复杂的安装情况,请访问MongoDB官网,查看完整的安装指导:
https://api.mongodb.com/python/current/installation.html
验证安装
请打开Python的交换环境,输入以下代码并回车,如果不报错,就表示安装成功:
import pymongo
PyMongo的使用
创建数据库
1
2
3
4
5
6
7
8
9
import pymongo
client = pymongo.MongoClient() 本地数据库不需要填写参数
database = client.person_info 创建名为person_info的数据库
col = database.people 在person_info数据库中创建people表
info_dict = {‘name’: ‘kingname’, ‘age’: 0, ‘sex’: ‘unknown’, ‘salary’: 888888}
col.insert(info_dict) 在表中插入数据
kingname = col.find()
for each in kingname:
print(each[‘salary’]) 查询数据
三:PyMongo的使用
导入模块
插入
MongoDB的插入操作非常简单。用到的方法为:insert(参数) ,插入的参数就是Python的字典。
1
2
data = {‘id’: 123, ‘name’: ‘ds’, ‘age’: 20, ‘salary’: 999999}
col.insert(data)
我们做爬虫,主要用MongoDB是来储存数据。所以主要使用的就是这个insert方法。
查找
MongoDB的查找功能对应的方法是:find(参数)和find_one(参数), 两个参数的类型均为Python字典,参数可以省略。其中,find_one()一次只返回一条信息。我们一般使用的最多的是find(参数)这个方法。
可以通过参数指定需要查找的内容。其中的参数可以省略不写。
1
2
content = col.find()
content = col.find({‘age’: 29})
第一行代码会返回你指定集合中的所有的内容。
第二行代码会返回所有年龄为29岁的人的记录。
这两种方式得到的结果content是一个pymongo对象,但是可以使用for循环展开。展开以后可以得到很多个字典。每个字典对应一条记录。
1
2
3
for row in content:
id = row[‘id’]
name = row[‘name’]
更新
更新用到的方法叫做update_one(参数1, 参数2)或者update_many(参数1,参数2), 前者只更新一条信息,后者更新所有符合要求的信息。这里的参数1,和参数2都是字典,都不能省略。请看代码:
1
2
col.update_one({‘age’: 20}, {’$set’:{‘name’: ‘kingname’}})
col.update_many({‘age’: 20}, {’$set’:{‘age’: 30}})
第一行代码的作用是,将第一个年龄为20岁的人的名字改为kingname。
第二行代码的作用是,将所有年龄为20岁的人的名字全部改为kingname。
删除
删除 用到的方法叫做delete_one(参数)或者delete_many(参数)这里的参数都是字典,不建议省略参数。delete_one(参数)只删除一条记录,delete_many(参数)删除所有的符合要求的记录。
1
2
col.delete_one({‘name’: ‘kingname’})
col.delete_many({‘name’: ‘kingname’})
第一行代码,删除第一个名字叫做kingname的人。
第二行代码,删除所有名字叫做kingname的人。
总结
我们在制作爬虫的过程中可能涉及到的PyMongo的知识主要就是这些。当然PyMongo还有一些其他的方法,如果大家有兴趣的话,可以查看PyMongo的官方文档:https://docs.mongodb.com/getting-started/python/client/
ORM 介绍
ORM(Object-relational mapping,对象关系映射),可以将对数据库的操作变为对象的操作。
MongoEngine就是MongoDB的一个ORM库,我们使用MongoEngine以后,就可以通过直接操作对象来控制MongoDB。
一般MongoEngine在基于Python的网页开发中应用较多。不过,在我们的爬虫上,也可以使用。
MongoEngine 的安装
使用pip 安装:pip install mongoengine
安装效果如下:
验证安装
打开python 交互环境,输入以下代码并回车,如果没有报错,则表示安装成功:
import mongoengine
MongoEngine 的使用
1.初始化连接
如果我们的MongoDB 是直接在本地电脑上面运行的,可以使用以下代码来连接到电脑上的MongoDB数据库:
1
2
from mongoengine import *
connect(‘数据库名’)
如果MongoDB不是运行在本地电脑上面的,就需要指定ip 地址和端口:
1
2
from mongoengine import *
connect(‘数据库名’, host=‘192.168.2.12’, port=3456) #请注意端口号是数字不是字符串
2.定义文档
定义一个类,这里我们以个人信息为例。这个类继承MongoEngine 的Document类。请注意,这里的类名People 对应了MongoDB中的集合名。类中的每一个变量,对应了每一条记录中的列名。
1
2
3
4
5
6
from mongoengine import *
class People(Document):
name = StringField(required=True) #请注意所有写了required=True的变量,在类初始化的时候都是必须填写的参数哦。
age = IntField(required=True)
sex = StringField(required=True)
salary = IntField() #这里的IntField 或者StringField 对应了数据类型
3.创建对象
初始化People类,创建一个对象:
1
2
kingname = People(name=‘kingname’, age=18, sex=‘male’, salary=99999) #注意这里的参数name, age 和sex是不可以省略的,但是salary可以省略
kingname.save()
当然,我们也可以这样写:
1
2
3
kingname = People(name=‘kingname’, age=18, sex=‘male’)
kingname.salary = 99999
kingname.save()
在信息已经保存以后,如果你想修改某个信息,你可以这样写:
1
2
kingname.age = 22
kingname.save()
这样就把年龄修改为22岁了。是不是比pymongo简单太多了?
4.读取对象
如果想读取所有的用户信息怎么办呢?非常简单:
1
2
3
4
for person in People.objects:
print(person.name)
print(person.age)
print(person.sex)
按条件搜索也非常简单,在People.objects后面加参数即可,例如搜索所有年龄为22岁的人:
1
2
for person in People.objects(age=22):
print(person.name)
你甚至会怀疑我到底是不是把这些信息写入到了数据库里面。你可以用RoboMongo读取一下数据库,看看是不是有一个集合叫做People,里面有我们添加进去的数据。
四:正则表达式的应用一
正则表达式介绍:
正则表达式(Regular Expression)是一段字符串,可以用来在一段文本中,查找,替换有规律的信息。
做一个比喻,假设在你的面前有一万个人,我让你去找一个人,他有如下特点:皮肤是绿色的,身高三米,内裤套在头上。那么只要这个人在这一万人中,你就能一眼找到他。如果我让你从这一万人中找十个有这种特征的人,你也可以在一瞬间把这十个人从这一万人中找出来。这个寻找的过程,在正则表达式中,叫做“匹配”。而你的大脑,天生就具有正则表达式的功能。
在计算机中,我们需要让计算机程序从一大段文本中找到我们需要的内容。就可以使用正则表达式来帮助我们。
使用正则表达式有如下步骤:
· 寻找规律
· 使用正则符号表示规律
· 提取信息
我们来举一个例子,下面有一段话:
今天天气不错,。password:88886666:password我刚刚不小心把我的密码写了出来。你能看到我的密码吗?
我发现我们都喜欢使用同样的密码,昨天我不小心看到了小红的密码password:11112222:password于是我用这个密码去入侵她的电脑,没想到成功了。
在她的电脑中,我发现了她的银行卡密码password:33334444:password于是我把她的银行卡密码也修改了。
在这一段文字中,一共出现了三个密码。这三个密码很有规律,他们都是 password:数字:password 这种形式的。那么,如果我可以有什么办法,能把符合 password:数字:password 这种格式的内容里面的数字提取出来,我就可以直接得到密码了。这就需要使用正则表达式来完成这个工作。
常用基本符号的基本意义:
点.
可以代表任意除\n
以外的字符
一个点号代表一个字符 就是一个占位符
星号*
表示匹配星号之前的0次或多次
问号?
匹配前面的0次或1次
\\
转义字符 不能单独使用 让有特殊意义的字符变成普通字符:\*
代表普通星号
让普通字符变成有意义的特殊字符\d
代表数字
括号的使用
()
是为了提取匹配的字符串。当我们使用正则表达式提取内容的时候,可能只想提取部分内容,于是我们需要使用括号来标记我们需要的内容。
通过下面这个例子说明:
有一个字符串
1
2
3
4
a = Pythonpachong
B = re.findall (‘Pyth…chong’,a)
Print(B) 返回变量a的所有字符Pythonpachong
B = re.findall (‘Pyth(…)chong’,a)
加上括号之后 只返回 onpa
提取数字
正则表达式里面,使用 \d
来表示一位数字。这里要强调一下,\d
虽然是由从左上向右下的斜杠和字母d构成的,但是我们要把\d
看成是一个正则表达式符号整体。从左上向右下的斜杠,名字叫做“反斜杠”,在正则表达式中是作为转义字符,不能单独使用。
如果要提取两个数字,我们可以使用 \d\d
,如果要提取三个数字,我们可以使用\d\d\d
,但是问题来了,如果我们不知道有这个数有多少位怎么办呢?就需要使用上一课讲到的+
号。+
号可以匹配它前面的符号一次或者多次。所以使用 \d+
,可以表示一个任意位数的数字。
我们的密码是123455677,请记住它。
当我们对这一段文字使用(\d+)
的时候的时候,就会把123455677给提取出来。
提取文本
对于文本来说,我们在爬虫中一般使用 .*?
这三个符号来完成。
我们知道点号表示任意非换行符的字符,*
号表示匹配它前面的字符零次或者任意多次。所以 .*
表示匹配一串任意长度的字符串任意次。这个时候必须在.*
的前后加其他的符号来限定范围,否则得到的结果就是原来的整个字符串。
如果在 .*
的后面加一个问号变成 .*?
,那么可以得到什么样的结果呢?问号表示匹配它前面的符号0次或者1次。于是 .*?
的意思就是,匹配一个能满足要求的最短字符串。
提取多行文本
只需把文本匹配模式中加入\n
:.*?\n.*?
· .*
外号贪心算法,获取最长的满足条件的字符串
匹配字符串中所有满足条件的内容
.*?
外号非贪心算法,获取最短的能满足条件的字符串
只匹配一个满足条件的内容后退出
五:正则表达式的应用二
导入模块
Python的正则表达式模块名字为 re ,我们可以使用:import re
来导入并使用。
findall 方法
Python的正则表达式模块包含一个findall方法,它可以以列表的形式返回所有满足要求的字符串
findall的函数原型为:
re.findall(正则规则, 内容, [flag=0])
findall的结果是一个列表,包含了所有的匹配到的结果
当我们需要提取某些内容的时候,需要使用小括号将这些内容括起来,这样才不会得到不相干的信息。如前文所说的一样
函数原型中,最后一个参数是可以省略的。当不省略的时候,可以起到一些辅助功能。例如忽略大小写,忽略换行符等等。我们这里以忽略换行符为例来进行说明,请看下图:
当我们抓取网页的时候,非常容易出现这样的情况,我们要匹配的内容中存在换行符\n
,这种情况下,要忽略换行符,就需要使用到re.S
这个flag. 我们对比上图的结果,就会发现flags的作用。虽然说匹配到的结果中出现了\n
这个符号,不过我们后期清洗数据的时候把它替换掉即可。
search 的使用
search方法可以返回第一个满足要求的字符串。一旦找到符合要求的内容,它就会停止查找。
search的函数原型为:
re.search(正则, 内容, flags=0)
search的结果是一个正则表达式的对