目录:
- 一,MySQL数据库安装与使用
- 二,python与MySQL整合
- 1.基本使用:
- 2.数据库在网络爬虫的应用
一,MySQL数据库安装与使用
我的一篇博文介绍MySQL安装和Windows命令行下使用,大家可以看下,这里不多赘述。
Windows平台下MySQL的安装和基本命令行使用 希望在使用MySQL与python进行整合前,能了解和掌握MySQL基本的数据库创建和操作。
二,python与MySQL整合
1.基本使用:
注意:许多新手往往会将py文件命名为pymysql,这样会导致与模块名重复(所以命名时避开pymysql就行了),无法使用并报错,见如下:
AttributeError: module 'pymysql' has no attribute 'connect'
python中与mysql交互最好的必须数pymysql库,这是一个第三方库,可以使用pip指令下载:
pip install pymysql
那么我们可以编写一个简单的python与数据库交互的程序:
import pymysql#千万不要把该文件名写成pymysql.py!
conn = pymysql.connect(host='localhost',user='root',password='')#连接对象(conn),本地则填localhost,用户填root,密码填入自己数据库设定的就行;
cur = conn.cursor() #光标对象(cur)
cur.execute("USE school") #选择school数据库
cur.execute("SELECT * FROM university WHERE id=1")#查找id=1并返回所有内容
print(cur.fetchone()) #在程序中打印查询到的信息
cur.close() #先关闭光标;
conn.close()#然后再关闭连接,否则会造成连接泄露现象;
输出效果:
连接 / 光标模式是数据库编程中常用的模式,刚刚接触数据库的时候,很难区分两种模式的不同。连接模式除了要连接数据库之外,还要发送数据库信息,处理回滚 操作(当一个查询或一组查询被中断时,数据库需要回到初始状态,一般用事务控制手段 实现状态回滚),创建新的光标对象,等等。 而一个连接可以有很多个光标。一个光标跟踪一种状态(state)信息,比如跟踪数据库的 使用状态。如果你有多个数据库,且需要向所有数据库写内容,就需要多个光标来处理。 光标还会包含最后一次查询执行的结果。通过调用光标函数,比如 cur.fetchone(),可以 获取查询结果。 用完光标和连接之后,千万记得把它们关闭。如果不关闭就会导致连接泄漏(connection leak),造成一种未关闭连接现象,即连接已经不再使用,但是数据库却不能关闭,因为数 据库不能确定你还要不要继续使用它。这种现象会一直耗费数据库的资源,所以用完数据 库之后记得关闭连接!
2.数据库在网络爬虫的应用
我们可以写一个爬取百度百科词条并将页面链接爬取保存在数据库中。在编写程序之前,我们得先创建数据库(scraping)和对应的表(pages),在命令行下,登入数据库后,我们可以输入以下(以分好分隔的,仅为命令展示,不含过程展示)命令:
>CREATE DATABASE scraping;
>USE scraping;
>CREATE TABLE pages (id BIGINT(7) NOT NULL AUTO_INCREMENT, title VARCHAR(200),
content VARCHAR(10000), created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY
(id));
但是,由于网络爬虫数据的特殊性(含有许多Unicode字符),我们要做一些特殊处理,因为在进行网络数据采集时,处理 Unicode 字符串是很痛苦的事情。默认情况下,MySQL 也不支持 Unicode 字符处理。不过你可以设置这个功能(这么做会增加数据库的占用空间):
>ALTER DATABASE scraping CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
>ALTER TABLE pages CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
>ALTER TABLE pages CHANGE title title VARCHAR(200) CHARACTER SET utf8mb4 COLLATE
utf8mb4_unicode_ci;
>ALTER TABLE pages CHANGE content content VARCHAR(10000) CHARACTER SET utf8mb4 CO
LLATE utf8mb4_unicode_ci;
这四行语句改变的内容有:数据库、数据表,以及两个字段的默认编码都从 utf8mb4(严格说来也属于 Unicode,但是对大多数 Unicode 字符的支持都非常不好)转变成了utf8mb4_unicode_ci。
这些对数据库的先前工作在很多爬虫中需要自己先前改写好,所以以后的python爬虫与数据库中都会跳过这一步骤(如有特殊变化的才会展示),希望大家能理解并记住!
下面开始写一个爬取百度百科词条页面的链接并保存在数据库中的程序:
from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
import pymysql
conn=pymysql.connect(host="localhost",user="root",password="",charset='utf8')#创建连接对象,注意要有charset字符设成utf8;
cur=conn.cursor()
def getLink(url): # 爬取处理url对应网页中链接的函数;
lists=[]#定义空列表,用于存储过滤好的连接
group=set()#用于链接去重的判断条件;
html = urlopen("https://baike.baidu.com" + url)
soup = BeautifulSoup(html, "html.parser")
link = soup.findAll("a", {"data-lemmaid": re.compile("[0-9]*")}) # 由目标标签特点写出正则表达式;
for i in link:
if i.attrs["href"] not in group:
group.add(i.attrs["href"])#同一链接对应标签有可能不同,所以以链接为去重判断标准;
lists.append(i)
return lists # 返回一个列表,包含页面所有链接;
def saveSQL(title,content):#数据库操作函数
cur.execute("USE scraping")#选择我们所要写入的数据库名;
cur.execute("INSERT INTO pages (title, content) VALUES (\"%s\",\"%s\")", (title, content)) #向数据库中插入对应变量的信息;
cur.connection.commit()#用光标进行连接确认
def processLink(links):#将链接传入到数据库里保存的函数
try:#检查是否运行错误;
for link in links:
title=link.text#标签信息的标题
content="https://baike.baidu.com"+link.attrs["href"]#标签的链接信息
saveSQL(title,content)
print("保存成功!")
except:
print("保存过程中出现错误!")
finally:#无论是否保存成功,都要关闭数据库,所以用finally语句;
cur.close()
conn.close()
def main():#主函数
links = getLink("/item/%E5%91%A8%E6%98%9F%E9%A9%B0") # 初始链接(以/item后面的形式)
processLink(links)
if __name__ == '__main__':
main()
这里有几点需要注意:首先,charset=‘utf8’ 要增加到连接字符串里。这是让连接 conn把所有发送到数据库的信息都当成 UTF-8 编码格式(当然,前提是数据库默认编码已经设置 成 UTF-8)。
然后要注意的是 saveSQL()函数。它有两个参数:title 和 content,并把这两个参数加到了一 个 INSERT 语句中并用光标执行,然后用光标进行连接确认。这是一个让光标与连接操作分离的好例子;当光标里存储了一些数据库与数据库上下文(context)的信息时,需要通过 连接的确认操作先将信息传进数据库,再将信息插入数据库。
最后,finally 语句是在程序主循环的外面,代码的最底下。这样做可以保证, 无论程序执行过程中如何发生中断或抛出异常光标和连接都会在程序结束前立即关闭。无论你是在采集网络,还是处理一个 打开连接的数据库,用 try…finally 都是一个好主意。
数据库中的存储效果和程序输出显示:
最后,文中如有不足,欢迎批评指正!!!