当前位置:首页 > 问答 > 正文

Python3怎么搞定网页数据库那些事儿,爬取数据存储一条龙操作指南

要搞定网页数据库那些事儿,用Python3实现爬取数据到存储的一条龙,说白了就是三步:把数据从网页上扒下来,把需要的信息从一堆代码里挑出来,然后规规矩矩地放进数据库里,下面我按这个顺序,结合一些常见的工具和思路给你讲清楚。

第一步:把网页“搬”到你的电脑里

这一步的核心工具是requests库,你就把它想象成一个特别听话的浏览器,你让它去哪个网址,它就去把那个网页的原始代码给你拿回来,这个库不是Python自带的,你需要先在命令行里输入pip install requests把它装上。

你想爬取豆瓣电影Top250的页面,代码大概长这样:

import requests
url = 'https://movie.douban.com/top250'
# 有些网站会检查浏览器身份,所以我们需要假装成一个真正的浏览器
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(url, headers=headers)
# 检查请求是否成功,状态码200代表成功
if response.status_code == 200:
    html_text = response.text  # 这里得到的就是网页的HTML源代码
    print(html_text) # 你可以先打印出来看看是什么样子
else:
    print('请求失败,状态码:', response.status_code)

这一步完成后,你手里拿到的html_text是一长串夹杂着各种标签(比如<div>, <p>)的文本,就像没拆开的快递包裹,我们需要下一步把它拆开。

第二步:从“包裹”里拆出你想要的东西

拆包裹的工具,最顺手的就是BeautifulSoup库(需要安装:pip install beautifulsoup4),它能把乱七八糟的HTML代码整理成一棵结构清晰的树,然后让你像问路一样,轻松找到想要的信息。

Python3怎么搞定网页数据库那些事儿,爬取数据存储一条龙操作指南

假设我们想从豆瓣电影的页面里提取每部电影的名字、评分和链接,通过浏览器的“检查”功能(在网页上右键点击就能看到),我们发现每个电影信息都放在一个classitemdiv里,那么代码可以这么写:

from bs4 import BeautifulSoup
# 用BeautifulSoup解析我们上一步拿到的HTML代码
soup = BeautifulSoup(html_text, 'html.parser')
# 找到所有class为'item'的div标签,这样我们就得到了一个电影列表
movie_list = soup.find_all('div', class_='item')
for movie in movie_list:
    # 在每个电影区块里,进一步寻找具体信息
    # 电影名在 class为'title'的span标签里,而且是第一个= movie.find('span', class_='title').text
    # 评分在 class为'rating_num'的span标签里
    rating = movie.find('span', class_='rating_num').text
    # 链接在 class为'hd'的div里的a标签的'href'属性里
    link = movie.find('div', class_='hd').a['href']
    # 把提取到的信息打印出来看看
    print(f"电影名:{title}, 评分:{rating}, 链接:{link}")

这样,我们就完成了信息的提取,你可能还需要处理多页数据,原理就是观察翻页时网址的变化规律,用一个循环重复第一步和第二步。

第三步:把整理好的信息“存”进数据库

数据库就像个高级的、有规律的仓库,这里我们用轻量级的SQLite数据库来举例,因为它不需要安装额外的软件,一个文件就是一个数据库,非常适合入门,Python自带操作SQLite的库sqlite3

Python3怎么搞定网页数据库那些事儿,爬取数据存储一条龙操作指南

存数据前,我们得先建好仓库的货架(表结构),我们想存电影名、评分和链接。

import sqlite3
# 连接到数据库文件,如果不存在会自动创建
conn = sqlite3.connect('douban_movies.db')
cursor = conn.cursor()
# 创建一张数据表,如果表已存在就先删除(避免重复运行出错)
cursor.execute('DROP TABLE IF EXISTS movies')
cursor.execute('''
    CREATE TABLE movies (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        rating REAL NOT NULL,
        link TEXT NOT NULL
    )
''')

货架建好了,现在可以把第二步提取到的数据存进去了,我们把第二步的循环和第三步的存储连起来。

# 假设我们已经有了movie_list
for movie in movie_list:= movie.find('span', class_='title').text
    rating = float(movie.find('span', class_='rating_num').text) # 评分转成小数
    link = movie.find('div', class_='hd').a['href']
    # 将数据插入到数据库表中
    cursor.execute('INSERT INTO movies (title, rating, link) VALUES (?, ?, ?)', (title, rating, link))
# 非常重要!执行完插入操作后,必须提交事务,数据才会真正保存到数据库
conn.commit()
# 关闭连接
conn.close()

到这里,一条龙操作就完成了,数据已经从网页上爬下来,处理干净,并稳稳地存进了你自己的数据库里。

一些重要的补充提醒:

  1. 遵守规则:在爬取任何网站前,一定要看看网站的robots.txt文件(通常在网站根目录下,比如https://www.example.com/robots.txt),这个文件告诉你网站允许和禁止爬取哪些内容,更要遵守法律法规和网站的使用条款。
  2. 温柔一点:不要用程序疯狂请求网站,这会给对方服务器造成压力,不道德甚至可能违法,在循环请求时,使用time.sleep(1)这样的语句暂停几秒,做个“有礼貌”的爬虫。
  3. 应对反爬:很多网站有反爬虫机制,除了上面用的伪装浏览器User-Agent,还可能遇到需要登录、验证码、动态加载(数据不是直接出现在HTML里,而是通过JavaScript后来加载的)等问题,对付动态加载,可能需要用到Selenium这样的工具来模拟真实浏览器行为,但那又是另一个话题了。

这条龙的核心骨架就是:requests(获取)-> BeautifulSoup(解析)-> sqlite3(存储),先把这条路走通,遇到具体问题再针对性地搜索解决,你就慢慢上手了。