Python爬虫教程:如何高效抓取多级页面数据(以电影天堂为例)

前面讲解的爬虫案例是单级页面数据的抓取。然而,有些时候,仅抓取一个单级页面是无法完成数据提取的。所以,本节将讲解怎样使用爬虫来抓取多级页面的数据。

Python爬虫教程:如何高效抓取多级页面数据(以电影天堂为例)

在爬虫进行的过程里,经常会遇到多级页面抓取的情况。接下来以抓取二级页面作为例子,对每级页面的作用进行阐释:

一级页面通过标签与二级页面相链接,只有在二级页面才能够提取到所需数据。接下来以电影天堂(点击访问)2020 新片精品为例进行讲解,要把每部影片的名称以及下载链接抓取下来。首先点击“更多”,从而进入一级页面,如下图所示:

图1:Python爬虫多级页面抓取

通过简单分析能够得知,寻找 url 规律时,一级页面和二级页面均为静态页面。接着分析 url 规律,点击第 1 页、第 2 页等,其规律如下:

https://www.dytt8.net/html/gndy/dyzz/list_23_1.html 位于第 1 页
https://www.dytt8.net/html/gndy/dyzz/list_23_2.html 位于第 2 页。
第 n 页的链接为 https://www.dytt8.net/html/gndy/dyzz/list_23_n.html 。

通过元素审查能够确定正则表达式,一级页面的元素结构情况如下:

图2:页面元素分析

其正则表达式如下:

 .*?

点击二级页面后进入详情页,利用开发者工具去分析所想要数据的网页元素,也就是电影名称以及下载链接,其正则表达式为:

(.*?)

.*?

爬虫增量抓取是一种效率低的程序,会大量消耗计算机资源。聚焦爬虫程序需每天对特定网站进行数据抓取,若每次都抓取已抓取过的数据,就会浪费时间和资源。增量爬虫是指通过监测网站更新情况,只抓取最新数据的方式,能大大降低资源消耗。

对于本节案例而言,电影天堂网站每天都有内容更新。所以,编写一个增量抓取的爬虫程序是很合适的。

那么怎样判断爬虫程序是否已抓取过二级页面的 url 呢?当您首次运行爬虫程序时,爬虫会把所有的 url 抓取下来,接着把这些 url 放入数据库里。为提升数据库的查询效率,您可以给每一个 url 生成专门的“指纹”。网站更新后,再次运行爬虫程序,此时程序只会抓取数据库中不存在的指纹。

2. 这里要将 url 指纹单独存放在一张表中,具体如下。

创建一个名为 movieskydb 的数据库,其字符集为 utf8。
use movieskydb;
create table request_finger(
finger char(60)
)charset=utf8;
create table movieinfo(
moviename varchar(300),
downloadaddr varchar(600)
)charset=utf8;

您可以使用 Python 内置的 md5 模块来生成加密“指纹”,具体如下:通过该模块生成 url 的指纹。

#导入模块
from hashlib import md5
#待加密的url
该链接为 https://www.dytt8.net/html/gndy/dyzz/20210226/61131.html 。
# 生成MD5对象
secret = md5()
# 加密url
secret.update(url.encode())
# 提取十六进制的加密串
finger = secret.hexdigest()
print(finger)

输出结果:

请提供具体需要改写的句子呀,没有看到横线下的内容呢。

3) 程序完整代码

# -*- coding: utf-8 -*-
from urllib import request
import re
import time
import random
import pymysql
from hashlib import md5
from ua_info import ua_list
import sys
class MovieSkySpider(object):
    def __init__(self):
self.url 等于 'https://www.dytt8.net/html/gndy/dyzz/list_23_' 加上一个占位符,这个占位符可以被替换为具体的数字,从而形成不同的页面链接。
        self.db = pymysql.connect(
本地主机、根用户、123456、movieskydb
            charset='utf8'
        )
self 拥有一个游标,这个游标是 self.db 的游标。
    # 1.请求函数
    def get_html(self, url):
headers 包含了一个键值对,键为 'User-Agent',值为从 ua_list 中随机选择的一个元素。
req 是一个 request.Request 对象,它的 url 属性被设置为指定的 url,它的 headers 属性被设置为指定的 headers。
        res = request.urlopen(req)
        # 本网站使用gb2312的编码格式
res 读取的内容通过 decode 方法以 'gb2312' 编码进行解码,并且忽略解码过程中的错误,得到的结果为 html 。
        return html
    # 2.正则解析函数
定义一个名为 re_func 的函数,该函数接收两个参数,分别是 re_bds 和 html。
re_bds 被用于创建一个正则表达式模式,该模式由 re.compile 函数进行编译,编译后的模式被赋值给变量 pattern ,并且在编译过程中使用了 re.S 标志。
pattern 在 html 中进行查找,查找到的结果存储在 r_list 中。
        return r_list
    # 3.提取数据函数
    def parse_html(self,one_url):
        # 调用请求函数,获取一级页面
self 获取了 one_url 的 HTML 内容并赋值给 one_html 。
        re_bds = '.*?
' # 获取二级页面链接 链接列表为:['/html//html/gndy/dyzz/20210226/61131.html', '/html/xxx', '', ''] self.re_func(re_bds,one_html) 被赋值给了 link_list 。 for link in link_list: # 判断是否需要爬取此链接 # 1.获取指纹 # 拼接二级页面url two_url 等于 'https://www.dytt8.net' 加上 link 。 s = md5() #加密url,需要是字节串 s.update(two_url.encode()) # 生成指纹,获取十六进制加密字符串, finger = s.hexdigest() # 2.通过函数判断指纹在数据库中是否存在 if self.is_hold_on(finger): # 抓取二级页面数据 self.save_html(two_url) 等待一段时间,这段时间的长度是在 1 到 2 之间随机生成的整数。 # 抓取后,把想用的url专属指纹存入数据库 “insert into request_finger values 后面跟一个占位符 %s” self 的游标执行插入操作 ins,传入参数 [finger] 。 self.db.commit() else: sys.exit('更新完成') # 4.判断链接是否已经抓取过 def is_hold_on(self,finger): # 查询数据库 sql 为 'select finger from request_finger where finger 等于 %s' execute()函数的返回值是受影响的行数,这个行数要么是 0,要么是非 0。 self.cursor 执行了 sql 语句,并且传入了 finger 参数,执行的结果赋值给了 r 。 # 如果为0表示没有抓取过 if not r: return True # 5.解析二级页面,获取数据(名称与下载链接) def save_html(self,two_url): self 获取了 two_url 的 HTML 内容并赋值给 two_html 。 re_bds = '

(.*?)

\
.*?以下是改写后的句子:该样式的背景颜色为特定的某种情况。(这里的“特定的某种情况”需根据具体文档中该样式的背景颜色实际情况来确定)' film_list 包含多个元素,每个元素是一个包含两个元素的元组,第一个元素为 'name',第二个元素为 'downloadlink',这些元组组成了一个列表,如 ('name','downloadlink')、()、() 等。 self.re_func(re_bds, two_html) 被赋值给了 film_list 。 print(film_list) # 插入数据库 sql 等于 '向 movieinfo 表中插入值,值为(%s,%s)' #L = list(film_list[0]) self 的游标执行了多个 SQL 语句,这些 SQL 语句是通过 film_list 提供的参数来执行的。 self.db.commit() #主函数 def run(self): # 二级页面后四页的正则表达式略有不同,需要重新分析 for i in range(1,4): url = self.url.format(i) self.parse_html(url) 如果 __name__ 的值为 '__main__' 。 spider = MovieSkySpider() spider.run()

若要查询数据库存储数据,执行以下命令即可:

mysql 执行从 movieinfo 表中查询所有数据的操作并以表格形式展示。

输出如下,如下图所示:

图3:MySQL数据库存储数据

在提取二级页面的数据时,需要留意该页面的类型。此网站在二级页面运用了两种类型的网页结构,另一种页面结构的正则表达式情况如下:

(.*?)

.*?若要抓取此类页面的数据,需要更换二级页面正则表达式。

你可能想看:
« 上一篇
下一篇 »

相关推荐

python爬虫教程PDF,Python爬虫书PDF

2026年09月02日

34阅读

外国教程python,python编程教学视频

2026年09月02日

28阅读

python简明教程沈洁元,python详细基础教程

2026年09月02日

22阅读

python库包教程,python 包

2026年09月02日

27阅读

python教程大全集,python教程600集

2026年09月02日

28阅读

python入门教程完整版,python零基础入门全套教程视频

2026年09月02日

23阅读