文章采集api(如何通过MySQL存储采集到的数据)

优采云 发布时间: 2022-02-21 06:08

  文章采集api(如何通过MySQL存储采集到的数据)

  MySQL是目前最流行的开源关系数据库管理系统。令人惊讶的是,一个开源项目的竞争力如此之强,以至于它的受欢迎程度不断接近另外两个闭源商业数据库系统:微软的 SQL Server 和甲骨文的甲骨文数据库(MySQL 于 2010 年被甲骨文收购)。)。

  它的受欢迎程度不辜负它的名字。对于大多数应用程序,MySQL 是显而易见的选择。它是一个非常灵活、稳定、功能齐全的 DBMS,许多顶级 网站 都在使用它:Youtube、Twitter、Facebook 等。

  由于使用广泛、免费、开箱即用,是web data采集项目中常用的数据库,在此文章我们介绍如何存储数据采集 通过 MySQL。

  安装 MySQL

  如果您是 MySQL 新手,您可能会觉得它有点麻烦。其实安装方法和安装其他软件一样简单。归根结底,MySQL 是由一系列数据文件组成的,存储在你的远程服务器或本地计算机上,其中收录了存储在数据库中的所有信息。

  在Windows上安装MySQL,在Ubuntu上安装MySQL,在MAC上安装MySQL具体步骤在这里:在所有平台上安装MySQL

  此处无需过多解释,按照视频操作即可。

  基本命令

  MySQL服务器启动后,与数据库服务器交互的方式有很多种。因为许多工具都是图形界面,所以您可以不使用 MySQL 的命令行(或很少使用)来管理数据库。phpMyAdmin 和 MySQL Workbench 等工具可以轻松查看、排序和创建数据库。但是,掌握命令行操作数据库还是很重要的。

  除了用户定义的变量名,MySQL 不区分大小写。例如,SELECT 与 select 相同,但习惯上所有 MySQL 关键词 的 MySQL 语句都以大写形式编写。大多数开发人员还喜欢使用小写字母作为数据库和数据表名称。

  首次登录 MySQL 数据库时,没有数据库来存储数据。我们需要创建一个数据库:

  CREATE DATABASE scraping_article DEFAULT CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI;

  因为每个 MySQL 实例可以有多个数据库,所以在使用数据库之前需要指定数据库名称:

  使用scraping_article

  从现在开始(直到关闭 MySQL 链接或切换到另一个数据库),所有命令都在这个新的“scraping_article”数据库中运行。

  所有的操作看起来都很简单。那么在数据库中新建表的操作方法应该也差不多吧?我们在库中新建一个表来存储采集的网页文章的数据:

  创建表文章;

  结果显示错误:

  错误 1113 (42000): 一个表必须至少有 1 列

  与数据库不同,MySQL 数据表必须有列,否则无法创建。要在 MySQL 中定义字段(数据列),我们还必须将字段定义放在 CREATE TABLE 语句之后的带括号的逗号分隔列表中:

  create table articles

(

id int auto_increment

primary key,

title varchar(64) null,

body text null,

summary varchar(256) null,

body_html text null,

create_time datetime default CURRENT_TIMESTAMP null,

time_updated datetime null,

link_text varchar(128) null

);

  每个字段定义由三部分组成:

  在字段定义列表的最后,还定义了一个“主键”(key)。MySQL使用这个主键来组织表的内容,方便以后快速查询。以后文章会介绍如何通过这些主键来提高数据库的查询速度,不过目前我们可以使用表的id列作为主键。

  语句执行完毕后,我们可以使用DESCRIBE查看数据表的结构:

  +--------------+--------------+------+-----+-------------------+----------------+

| Field | Type | Null | Key | Default | Extra |

+--------------+--------------+------+-----+-------------------+----------------+

| id | int(11) | NO | PRI | NULL | auto_increment |

| title | varchar(64) | YES | | NULL | |

| body | text | YES | | NULL | |

| summary | varchar(256) | YES | | NULL | |

| body_html | text | YES | | NULL | |

| create_time | datetime | YES | | CURRENT_TIMESTAMP | |

| time_updated | datetime | YES | | NULL | |

| link_text | varchar(128) | YES | | NULL | |

+--------------+--------------+------+-----+-------------------+----------------+

8 rows in set (0.03 sec)

  现在这张表是空表,我们插入数据看看,如下图:

  INSERT INTO articles(title,body,summary,body_html,link_text) VALUES ("Test page title","Test page body.","Test page summary.","<p>Test page body.","test-page");</p>

  这里需要注意,虽然articles表有8个字段(id、title、body、summary、body_html、create_time、time_update、link_text),但实际上我们只插入了5个字段(title、body、summary、body_html、link_text) ) ) 数据。因为id字段是自动递增的(MySQL每次插入数据时默认递增1),一般不需要处理。另外create_time字段的类型是current_timestamp,时间戳是通过插入的默认。

  当然,我们也可以自定义字段内容来插入数据:

  INSERT INTO articles(id,title,body,summary,body_html,create_time,link_text) VALUES (4,"Test page title","Test page body.","Test page summary.","<p>Test page body.","2021-11-20 15:51:45","test-page");</p>

  只要你定义的整数不在数据表的id字段中,就可以插入到数据表中。但是,这非常糟糕;除非绝对必要(比如程序中缺少一行数据),否则让 MySQL 自己处理 id 和 timestamp 字段。

  现在表中有一些数据,我们可以通过多种方式查询这些数据。以下是 SELECT 语句的一些示例:

  SELECT * FROM articles WHERE id=1;

  该语句告诉 MySQL “从文章表中选择 id 等于 2 的所有数据”。此星号 (*) 是通配符,表示所有字段。这行语句将显示所有满足条件的字段(其中 id=1))。如果没有 id 等于 1 的行,它将返回一个空集。例如,以下不区分大小写的查询将返回标题字段中收录“test”的所有行的所有字段(% 符号表示 MySQL 字符串通配符):

  SELECT * FROM articles WHERE title LIKE "%test%";

  但是如果你有很多字段并且你只想返回其中的一部分呢?您可以使用以下命令代替星号:

  SELECT title, body FROM articles WHERE body LIKE "%test%";

  这将只返回正文内容收录“test”的所有行的标题和正文字段。

  DELETE 语句的语法类似于 SELECT 语句:

  DELETE FROM articles WHERE id=1;

  由于数据库的数据删除无法恢复,建议在执行DELETE语句前使用SELECT确认要删除的数据(上述删除语句可以使用SELECT * FROM文章WHERE id=1;查看),以及然后将 SELECT * 替换为 DELETE 就可以了,这是一个好习惯。很多程序员都有过 DELETE 误操作的悲惨故事,也有一些恐怖的故事是有人惊慌失措的忘记在语句中输入 WHERE,结果所有*敏*感*词*都被删除了。不要让这种事情发生在你身上!

  要介绍的另一件事是 UPDATE 语句:

  UPDATE articles SET title="A new title", body="Some new body." WHERE id=4;

  以上只使用了最基本的 MySQL 语句来做一些简单的数据查询、创建和更新。

  与 Python 集成

  Python 没有对 MySQL 的内置支持。但是,有很多开源的可以用来和 MySQL 交互,Python 2.x 和 Python 3.x 版本都支持。最著名的一个是 PyMySQL。

  我们可以使用pip来安装,执行如下命令:

  python3 -m pip 安装 PyMySQL

  安装完成后,我们就可以使用 PyMySQL 包了。如果您的 MySQL 服务器正在运行,您应该能够成功执行以下命令:

  import pymysql

import os

from dotenv import load_dotenv

class DataSaveToMySQL(object):

def __init__(self):

# loading env config file

dotenv_path = os.path.join(os.getcwd(), &#39;.env&#39;)

if os.path.exists(dotenv_path):

load_dotenv(dotenv_path)

conn = pymysql.connect(host=os.environ.get(&#39;MYSQL_HOST&#39;), port=os.environ.get(&#39;MYSQL_PORT&#39;),

user=os.environ.get(&#39;MYSQL_USER&#39;), password=os.environ.get(&#39;MYSQL_PASSWORD&#39;),

db=os.environ.get(&#39;MYSQL_DATABASES&#39;))

cur = conn.cursor()

cur.execute("SELECT * FROM articles WHERE id=4;")

print(cur.fetchone())

cur.close()

conn.close()

  这个程序有两个对象:一个连接对象(conn)和一个游标对象(cur)。

  连接/游标模式是数据库编程中常用的模式。当您不熟悉数据库时,有时很难区分这两种模式之间的区别。连接方式除了连接数据库外,还发送数据库信息,处理回滚操作(当一个查询或一组查询中断时,数据库需要回到初始状态,一般使用事务来实现状态回滚),创建新游标等

  一个连接可以有很多游标,一个游标跟踪一种状态信息,比如跟踪数据库的使用状态。如果您有多个数据库,并且需要写入所有数据库,则需要多个游标来处理。游标还可以收录上次查询执行的结果。查询结果可以通过调用cur.fetchone()等游标函数获得。

  请记住在使用完连接和游标后关闭它们。如果不关闭,会导致连接泄漏(connection leak),造成连接关闭现象,即连接不再使用,但是数据库无法关闭,因为数据库不确定是否你想继续使用它。这种现象会一直消耗数据库资源,所以使用数据库后记得关闭连接!

  刚开始时,您要做的就是将 采集 的数据保存到数据库中。我们继续采集blog文章的例子来演示如何实现数据存储。

  import pymysql

import os

from dotenv import load_dotenv

from config import logger_config

from utils import connection_util

class DataSaveToMySQL(object):

def __init__(self):

# loading env config file

dotenv_path = os.path.join(os.getcwd(), &#39;.env&#39;)

if os.path.exists(dotenv_path):

load_dotenv(dotenv_path)

# MySQL config

self._host = os.environ.get(&#39;MYSQL_HOST&#39;)

self._port = int(os.environ.get(&#39;MYSQL_PORT&#39;))

self._user = os.environ.get(&#39;MYSQL_USER&#39;)

self._password = os.environ.get(&#39;MYSQL_PASSWORD&#39;)

self._db = os.environ.get(&#39;MYSQL_DATABASES&#39;)

self._target_url = &#39;https://www.scrapingbee.com/blog/&#39;

self._baseUrl = &#39;https://www.scrapingbee.com&#39;

self._init_connection = connection_util.ProcessConnection()

logging_name = &#39;store_mysql&#39;

init_logging = logger_config.LoggingConfig()

self._logging = init_logging.init_logging(logging_name)

def scrape_data(self):

get_content = self._init_connection.init_connection(self._target_url)

if get_content:

parent = get_content.findAll("section", {"class": "section-sm"})[0]

get_row = parent.findAll("div", {"class": "col-lg-12 mb-5 mb-lg-0"})[0]

get_child_item = get_row.findAll("div", {"class": "col-md-4 mb-4"})

for item in get_child_item:

# 获取标题文字

get_title = item.find("a", {"class": "h5 d-block mb-3 post-title"}).get_text()

# 获取发布时间

get_release_date = item.find("div", {"class": "mb-3 mt-2"}).findAll("span")[1].get_text()

# 获取文章描述

get_description = item.find("p", {"class": "card-text post-description"}).get_text()

self.article_save_mysql(title=get_title, description=get_description, release_date=get_release_date)

else:

self._logging.warning(&#39;未获取到文章任何内容,请检查!&#39;)

def article_save_mysql(self, title, description, release_date):

connection = pymysql.connect(host=self._host, port=self._port, user=self._user, password=self._password,

db=self._db, charset=&#39;utf-8&#39;)

with connection.cursor() as cursor:

# Create a new record

sql = "INSERT INTO articles (title,summary,create_time) VALUES (%s,%s,%s);"

cursor.execute(sql, (title, description, release_date))

# connection is not autocommit by default. So you must commit to save

# your changes.

connection.commit()

  这里需要注意几点:首先,将 charset='utf-8' 添加到连接字符串中。这是为了让conn把所有发送到数据库的信息都当作utf-8编码格式(当然前提是数据库默认编码设置为UTF-8)。

  然后需要注意article_save_mysql函数。它有3个参数:title、description和release_date,并将这两个参数添加到INSERT语句中并用游标执行,然后用游标确认。这是将光标与连接分开的一个很好的例子;当游标存储一些数据库和数据库上下文信息时,需要通过连接确认才能将信息传递到数据库中,然后再将信息插入到数据库中。

  上述代码没有使用 try...finally 语句关闭数据库,而是使用 with() 关闭数据库连接。在上一期中,我们也使用了 with() 来关闭 CSV 文件。

  PyMySQL的规模虽然不大,但里面有一些非常实用的功能,在本文章中就不演示了。具体请参考 Python DBAPI 标准文档。

  以上是关于将采集的内容保存到MySQL。本示例的所有代码都托管在 github 上。

  github:

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线