爬虫初级操作(二)
本篇内容为 python 网络爬虫初级操作的简单介绍,内容主要有以下 2 部分:
- 解析网页
- 数据库
解析网页
一般来说,解析网页有三种方式:正则表达式、BeautifulSoup、lxml。其中正则表达式较难,BeautifulSoup 适合初学者,可以快速掌握提取网页中数据的方法。
正则表达式
常见的正则字符和含义如下:
. 匹配任意字符,除了换行符 * 匹配前一个字符 0 次或多次 + 匹配前一个字符 1 次或多次 ? 匹配前一个字符 0 次或 1 次 ^ 匹配字符串开头 $ 匹配字符串末尾 () 匹配括号内表示式,也表示一个组 \s 匹配空白字符 \S 匹配任何非空白字符 \d 匹配数字,等价于[0-9] \D 匹配任何非数字,等价于[^0-9] \w 匹配字母数字,等价于[A-Za-z0-9] \W 匹配非字母数字,等价于[^A-Za-z0-9] [] 用来表示一组字符
Python 正则表达式有以下 3 种方法:re.match
方法:从字符串起始位置匹配一个模式,如果从起始位置匹配了,match()就返回none。
语法 re.match(pattern, string, flags=0)
pattern
:正则表达式string
:要匹配的字符串flags
:控制正则表达式的匹配方式,如 是否区分大小写、多行匹配等
re.search
方法:只能从字符串的起始位置进行匹配。
find_all
方法:可以找到所有的匹配。
BeautifulSoup
BeautifulSoup
从 HTML
或 XML
文件中提取数据。首先需要使用命令行来进行安装:
pip install bs4
在使用的时候需要导入:
from bs4 import BeautifulSoup
例如使用 BeautifulSoup
获取博客主页文章的标题,代码和注释如下:
import requests from bs4 import BeautifulSoup link = 'http://www.santostang.com/' headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'} r = requests.get(link, headers=headers) # 将网页响应体的字符串转换为soup对象 soup = BeautifulSoup(r.text, 'html.parser') first_title = soup.find('h1', class_='post-title').a.text.strip() print('第一篇文章的标题是:', first_title) title_list = soup.find_all('h1', class_='post-title') for i in range(len(title_list)): title = title_list[i].a.text.strip() print('第 %s 篇文章的标题是: %s' % (i+1, title))
运行得到结果:
成功抓取到所需内容。
关于 BeautifulSoup
, 我们最后再来看一个实战项目:爬取北京二手房价格。代码如下:
import requests from bs4 import BeautifulSoup import time headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'} for i in range(1,11): link = 'https://beijing.anjuke.com/sale/' r = requests.get(link, headers=headers) print('第', i, '页') soup = BeautifulSoup(r.text, 'lxml') house_list = soup.find_all('li', class_='list-item') for house in house_list: name = house.find('div', class_='house-title').a.text.strip() price = house.find('span', class_='price-det').text.strip() price_area = house.find('span', class_='unit-price').text.strip() no_room = house.find('div', class_='details-item').span.text area = house.find('div', class_='details-item').contents[3].text floor = house.find('div', class_='details-item').contents[5].text year = house.find('div', class_='details-item').contents[7].text broker = house.find('span', class_='brokername').text broker = broker[1:] address = house.find('span', class_='comm-address').text.strip() address = address.replace('\xa0\xa0\n ', ' ') tag_list = house.find_all('span', class_='item-tags') tags = [i.text for i in tag_list] print(name, price, price_area, no_room, area, floor, year, broker, address, tags) time.sleep(5)
这样就成功爬取了安居客上前 10 页的北京二手房价格。
数据库
数据存储分为两种,存储在文件(TXT和CSV)中和存储在数据库(MySQL关系数据库和MongoDB数据库)中。
CSV (Comma-Separated Values)
是逗号分隔值的文件格式,其文件以纯文本的形式存储表格数据(数字和文本)。
CSV 文件的每一行都用换行符分隔,列与列之间用逗号分隔。
MySQL
是一种关系数据库管理系统,所使用的是SQL
语言,是访问数据库最常用的标准化语言。关系数据库(建立在关系模型基础上的数据库)将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了写入和提取的速度,数据的存储也比较灵活。
关于存储在文件的方法这里不再赘述,下面首先介绍如何存储至MySQL
数据库。
你需要先到官网下载并安装 MySQL
数据库,博主用的是 macOS Sierra 系统,在安装完成后,打开系统偏好设置,如下图:
最下方出现 MySQL
的图标,打开并连接,如下图所示:
打开终端,在终端中输入添加MySQL路径的命令:
PATH="$PATH":/usr/local/mysql/bin
继续输入登录到MySQL
的命令:mysql -u root -p
,然后输入密码即可成功登录。成功登录界面如下:
接下来介绍MySQL的基本操作:
- 创建数据库
- 创建数据表
创建数据表必须指明每一列数据的名称(column_name)和类别(column_type)。
在上图中,创建了 4 个变量:id, url, content, created_time
。其中id
的类别是整数INT
,属性为自己增加(AUTO_INCREMENT)
。新添加数据的数值会自动加 1。PRIMARY KEY
的关键字用于将id
定义为主键。
url
和content
的类别是可变长度的字符串VARCHAR
,括号中的数字代表长度的最大值,NOT NULL
表示url
和content
不能为空。created_time
为该数据添加时间,不需要设置,因为有时间戳,它会自动根据当时的时间填入。
创建数据表后,可查看数据表的结构:
- 在数据表中插入数据
这里插入了url
和content
两个属性,id
是自动递增的,created_time
是数据加入的时间戳,这两个变量会自动填入。
- 从数据表中提取数据
由上图,我们可以看到提取数据有 3 种方法:
(1)将id
等于 1 的数据行提取出来;
(2)提取只看部分字段的数据;
(3)提取包含部分内容的数据。
- 删除数据
⚠️注意,如果没有指定 WHERE
子句,用DELETE FROM urls
将会导致MySQL
表中的所有记录被删除,即误删除整张表。
- 修改数据
由于id
和created_time
是数据库自动填入的,因此这一行数据的id
为 2。
更多操作可参考菜鸟教程。
下面介绍使用Python
操作MySQL
数据库,依次使用下令命令安装mysqlclient
:
brew install mysql export PATH=$PATH:/usr/local/mysql/bin pip install MySQL-Python pip3 install mysqlclient
出现下列文字即安装成功:
用Python
操作MySQL
数据库,我们以在博客爬取标题和 url 地址为例,具体代码和解释如下:
#coding=UTF-8 import MySQLdb import requests from bs4 import BeautifulSoup # connect() 方法用于创建数据库的连接,里面可以指定参数:用户名,密码,主机等信息 #这只是连接到了数据库,要想操作数据库需要创建游标 conn = MySQLdb.connect(host='localhost', user='root', passwd='your_password', db='MyScraping', charset='utf8') # 通过获取到的数据库连接conn下的cursor()方法来创建游标。 cur=conn.cursor() link = 'http://www.santostang.com/' headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'} r = requests.get(link, headers=headers) soup = BeautifulSoup(r.text, 'html.parser') title_list = soup.find_all('h1', class_='post-title') for eachone in title_list: url = eachone.a['href'] title = eachone.a.text.strip() # 创建数据表,通过游标cur 操作execute()方法可以写入纯sql语句。通过execute()方法中写如sql语句来对数据进行操作 cur.execute('INSERT INTO urls (url, content) VALUES (%s, %s)', (url, title)) cur.close() conn.commit() conn.close()
最后,我们来介绍如何存储至MongoDB
数据库。
首先要知道NoSQL
泛指非关系型数据库,数据之间无关系,具有非常高的读写性能,而MongoDB
是其中非常流行的一种数据库。它是一种关系数据库管理系统,所使用的是SQL语言,是访问数据库最常用的标准化语言。
下面仍以上述的在博客爬取标题和 url 地址为例。
第一步连接 MongoDB
客户端,然后连接数据库blog_database
,再选择该数据的集合blog
。如果它们不存在,就会自动创建一个,代码示例如下:
from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.blog_database collection = db.blog
第二步爬取博客主页的所有文章标题存储至MongoDB
数据库,代码如下:
import requests import datetime from bs4 import BeautifulSoup from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.blog_database collection = db.blog link = 'http://www.santostang.com/' headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'} r = requests.get(link, headers=headers) soup = BeautifulSoup(r.text, 'html.parser') title_list = soup.find_all('h1', class_='post-title') for eachone in title_list: url = eachone.a['href'] title = eachone.a.text.strip() post = {'url': url, 'title': title, 'date': datetime.datetime.utcnow() } collection.insert_one(post)
重点在最后一部分的代码,首先将爬虫获取的数据存入post
的字典中,然后使用insert_one
加入集合collection
中。
最后,启动MongoDB
查看结果。
打开终端输入:
sudo mongod --config /usr/local/etc/mongod.conf
确认权限后,保持当前终端不关,新建终端依次输入:
mongod mongo
出现以下文字表示连接成功:
然后,输入:
use blog_database db.blog.find().pretty()
就查询到数据集合的数据了,如下图所示:
同时注意到,它是JSON
格式的。
更多使用 Python 来操作 MongoDB 数据库的知识,可以参考 PyMongo官网。
本文为崔庆才博客和唐松的《Python网络爬虫从入门到实践》学习记录与总结,具体内容可参考二者。博主在学习过程中的练习代码也已上传至 GitHub。
不足之处,欢迎指正。