您当前的位置: 首页 >  Python

止步前行

暂无认证

  • 0浏览

    0关注

    247博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Python爬虫实战

止步前行 发布时间:2022-08-22 10:29:46 ,浏览量:0

文章目录
  • 1. 引言
  • 2. 页面分析
    • 2.1 页面元素分析
    • 2.2 分页分析
    • 2.3 页面详情页面
    • 2.4 下载链接
  • 3. 代码
    • 3.1 数据库结构
    • 3.2 步骤
      • 3.2.1 根据url获取页面结构
      • 3.2.2 解析页面数据
      • 3.2.3 数据存入数据库
  • 4. 测试结果
  • 5. 完整代码

1. 引言

注:勿用于非法用途。

之前学习过Python的基础知识,目前需要做语音识别和语义分析相关工作,所有又得继续学习Python

下面就学习下如何使用Python进行爬虫,就当练练手吧。

Python 特点:

  • Python是一种面向对象的脚本语言,使用时无需编译,因此也称作解释性语言,其结构简单,语法规则明确,关键词定义较少,非常适合初学者。

  • Python拥有丰富的内置库函数,对于处理网络、文件、GUI、数据库、文本等十分便捷,同时支持大量第三方库,比如最常用的用于科学计算的NumpySciPy等库,提供了非常简洁、高效的开发平台。

2. 页面分析 2.1 页面元素分析

下面要爬虫的是一个电影网站。本人平时看电影,都是用这个网站,想把爬完的数据存入mysql数据库,再用RUOYI开源项目做一个后台管理系统。

这个电影网站的分类共有20个,动作片、剧情片、爱情片、喜剧片……但它们都很有规律,查看网页源码,可以发现:

在这里插入图片描述

剧情片 
喜剧片 
动作片 
爱情片 
科幻片 
动画片 
悬疑片 
惊悚片 
恐怖片 
纪录片 
音乐歌舞题材电影 
传记片 
历史片 
战争片 
犯罪片 
奇幻电影 
冒险电影 
灾难片 
武侠片 
古装片 

对于每个分类的完整地址,前面都会加上网站域名。自己加上吧。

2.2 分页分析

对于每个电影类别的首页,地址都是:

域名 + /2/index.html

对于每个的电影院类别,从第二页开始,地址都是:

域名 + /2/index_2.html # 第二页

域名 + /2/index_3.html # 第三页

域名 + /2/index_4.html # 第四页

可以看出规律了吧。

2.3 页面详情页面

对于进入页面详情页,要观察页面列表的结构,入下图:

在这里插入图片描述

a标签指定了跳转的具体路径和电影的名称,还有评分,这几个信息可以获取到。

2.4 下载链接

进入得到电影详情页后,可以看到如下页面结构:

在这里插入图片描述

这样就可以获取到电影额下地址啦。

注意:此处的下载地址可能不止一个。

3. 代码 3.1 数据库结构
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_video_film
-- ----------------------------
DROP TABLE IF EXISTS `t_video_film`;
CREATE TABLE `t_video_film`  (
  `film_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `film_type_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `film_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `film_score` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `film_link` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `film_magnet_1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `film_magnet_2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `film_magnet_3` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

需要安装pymysql

pip installl pymysql

3.2 步骤 3.2.1 根据url获取页面结构
'''
    功能:访问 url 的网页,获取网页内容并返回
    参数:url :目标网页的 url
    返回:目标网页的 html 内容
'''
def get_data(url):
    headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
    }

    try:
        r = requests.get(url, headers=headers)
        r.encoding="GBK"
        r.raise_for_status()
        return r.text

    except requests.HTTPError as e:
        print(e)
        print("HTTPError")
    except requests.RequestException as e:
        print(e)
    except:
        print("Unknown Error !")

此处要注意的是,要查看爬虫网站的编码,不然会乱码,具体如下:

在这里插入图片描述

3.2.2 解析页面数据

使用BeautifulSoup进行页面解析,具体可以参考另一篇文章:

https://blog.csdn.net/zxd1435513775/article/details/120280335

'''
    功能:提取 html 页面信息中的关键信息,并整合一个数组并返回
    参数:html 根据 url 获取到的网页内容
    返回:存储有 html 中提取出的关键信息的数组
'''
def parse_data(html):

    bsobj = bs4.BeautifulSoup(html, 'html.parser')
    info = []

    # 获取电影列表
    tbList = bsobj.find_all('table', attrs={'class': 'tbspan'})

    # 对电影列表中的每一部电影单独处理
    for item in tbList:

        movie = []
        score = item.find_all('tr')[2].find_all('td')[1].find_all('font')[1].text
        link = item.b.find_all('a')[1]
        # 获取电影的名称
        name = link["title"]
        # 获取详情页面的 url
        url = 域名 + link["href"]
        # 将数据存放到电影信息列表里
        movie.append('20')
        movie.append('古装片')
        movie.append(name)
        movie.append(score)
        movie.append(url)

        try:
            # 访问电影的详情页面,查找电影下载的磁力链接
            temp = bs4.BeautifulSoup(get_data(url), 'html.parser')
            tbody = temp.find_all('tbody')

            # 下载链接有多个(也可能没有),这里将所有链接都放进来
            for i in tbody:
                download = i.a.text
                movie.append(download)

            # print(movie)
            # 将此电影的信息加入到电影列表中
            info.append(movie)
        except Exception as e:
            print(e)
    return info
3.2.3 数据存入数据库
def save_data(data):
    db = pymysql.connect(host='localhost', user='root', password='', port=3306, db = 'film')
    cur = db.cursor()  ##获取游标
    sql3 = 'insert into t_video_film(film_type,film_type_name,film_name) values(%s,%s,%s)'
    sql4 = 'insert into t_video_film(film_type,film_type_name,film_name,film_score) values(%s,%s,%s,%s)'
    sql5 = 'insert into t_video_film(film_type,film_type_name,film_name,film_score,film_link) values(%s,%s,%s,%s,%s)'
    sql6 = 'insert into t_video_film(film_type,film_type_name,film_name,film_score,film_link,film_magnet_1) values(%s,%s,%s,%s,%s,%s)'
    sql7 = 'insert into t_video_film(film_type,film_type_name,film_name,film_score,film_link,film_magnet_1,film_magnet_2) values(%s,%s,%s,%s,%s,%s,%s)'
    sql8 = 'insert into t_video_film(film_type,film_type_name,film_name,film_score,film_link,film_magnet_1,film_magnet_2,film_magnet_3) values(%s,%s,%s,%s,%s,%s,%s,%s)'
    for i in data:
        print(i)
        if len(i) == 3:
            cur.execute(sql3, (i[0], i[1], i[2]))
        elif len(i) == 4:
            cur.execute(sql4, (i[0], i[1], i[2], i[3]))
        elif len(i) == 5:
            cur.execute(sql5, (i[0], i[1], i[2], i[3], i[4]))
        elif len(i) == 6:
            cur.execute(sql6, (i[0], i[1], i[2], i[3], i[4], i[5]))
        elif len(i) == 7:
            cur.execute(sql7, (i[0], i[1], i[2], i[3], i[4], i[5], i[6]))
        else:
            cur.execute(sql8, (i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]))
    db.commit()

对于有多个下载链接的电影,要单独处理。

4. 测试结果

在这里插入图片描述

在这里插入图片描述

5. 完整代码

代码仅供参考,有很多可以优化的地方。

import requests
import bs4
import pymysql

def get_data(url):
    '''
    功能:访问 url 的网页,获取网页内容并返回
    参数:url :目标网页的 url
    返回:目标网页的 html 内容
    '''
    headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
    }

    try:
        r = requests.get(url, headers=headers)
        r.encoding="GBK"
        r.raise_for_status()
        return r.text

    except requests.HTTPError as e:
        print(e)
        print("HTTPError")
    except requests.RequestException as e:
        print(e)
    except:
        print("Unknown Error !")


def parse_data(html):
    '''
    功能:提取 html 页面信息中的关键信息,并整合一个数组并返回
    参数:html 根据 url 获取到的网页内容
    返回:存储有 html 中提取出的关键信息的数组
    '''
    bsobj = bs4.BeautifulSoup(html, 'html.parser')
    info = []

    # 获取电影列表
    tbList = bsobj.find_all('table', attrs={'class': 'tbspan'})

    # 对电影列表中的每一部电影单独处理
    for item in tbList:

        movie = []
        score = item.find_all('tr')[2].find_all('td')[1].find_all('font')[1].text
        link = item.b.find_all('a')[1]
        # 获取电影的名称
        name = link["title"]
        # 获取详情页面的 url
        url = 域名 + link["href"]
        # 将数据存放到电影信息列表里
        movie.append('20')
        movie.append('古装片')
        movie.append(name)
        movie.append(score)
        movie.append(url)

        try:
            # 访问电影的详情页面,查找电影下载的磁力链接
            temp = bs4.BeautifulSoup(get_data(url), 'html.parser')
            tbody = temp.find_all('tbody')

            # 下载链接有多个(也可能没有),这里将所有链接都放进来
            for i in tbody:
                download = i.a.text
                movie.append(download)

            # print(movie)
            # 将此电影的信息加入到电影列表中
            info.append(movie)
        except Exception as e:
            print(e)
    return info

def save_data(data):
    '''
    功能:将 data 中的信息输出到文件中/或数据库中。
    参数:data 将要保存的数据
    '''
    # print(data)

    db = pymysql.connect(host='localhost', user='root', password='123456', port=3306, db = 'film')
    cur = db.cursor()  ##获取游标
    sql3 = 'insert into t_video_film(film_type,film_type_name,film_name) values(%s,%s,%s)'
    sql4 = 'insert into t_video_film(film_type,film_type_name,film_name,film_score) values(%s,%s,%s,%s)'
    sql5 = 'insert into t_video_film(film_type,film_type_name,film_name,film_score,film_link) values(%s,%s,%s,%s,%s)'
    sql6 = 'insert into t_video_film(film_type,film_type_name,film_name,film_score,film_link,film_magnet_1) values(%s,%s,%s,%s,%s,%s)'
    sql7 = 'insert into t_video_film(film_type,film_type_name,film_name,film_score,film_link,film_magnet_1,film_magnet_2) values(%s,%s,%s,%s,%s,%s,%s)'
    sql8 = 'insert into t_video_film(film_type,film_type_name,film_name,film_score,film_link,film_magnet_1,film_magnet_2,film_magnet_3) values(%s,%s,%s,%s,%s,%s,%s,%s)'
    for i in data:
        print(i)
        if len(i) == 3:
            cur.execute(sql3, (i[0], i[1], i[2]))
        elif len(i) == 4:
            cur.execute(sql4, (i[0], i[1], i[2], i[3]))
        elif len(i) == 5:
            cur.execute(sql5, (i[0], i[1], i[2], i[3], i[4]))
        elif len(i) == 6:
            cur.execute(sql6, (i[0], i[1], i[2], i[3], i[4], i[5]))
        elif len(i) == 7:
            cur.execute(sql7, (i[0], i[1], i[2], i[3], i[4], i[5], i[6]))
        else:
            cur.execute(sql8, (i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]))
    db.commit()


'''
剧情片 6687/6804
喜剧片 4203/4263
动作片 3698/3756
爱情片 2518/2561
科幻片 1256/1258  
动画片 936/988
悬疑片 1424/1428
惊悚片 3759/3792
恐怖片 1547/1563
纪录片 237/238
音乐歌舞题材电影  289/289
传记片 418/430
历史片 568/572
战争片 637/652
犯罪片 2198/2227
奇幻电影 1276/1279
冒险电影 /1727  58
灾难片 81/81 3
武侠片 75/75 3
古装片 196/197 7
'''
def main():
    # 循环爬取多页数据
    for page in range(1, 8):
        print('正在爬取:第' + str(page) + '页......')
        # 根据之前分析的 URL 的组成结构,构造新的 url
        if page == 1:
            index = 'index'
        else:
            index = 'index_' + str(page)
        url = 域名 + index + '.html'
        # 依次调用网络请求函数,网页解析函数,数据存储函数,爬取并保存该页数据
        html = get_data(url)
        movies = parse_data(html)
        save_data(movies)
        print('第' + str(page) + '页完成!')
if __name__ == '__main__':
    print('爬虫启动成功!')
    main()
    print('爬虫执行完毕!')
关注
打赏
1657848381
查看更多评论
立即登录/注册

微信扫码登录

0.0522s