利用python爬虫(案例1)--电影天堂的小电影们

学习笔记
前言:此案例中,要求抓取电影天堂网站内最新电影栏里的电影名称,以及该电影的下载链接,并将这些数据存储在数据库中。

案例(电影天堂数据抓取)

首先,我们看一下要爬取的网页

再确定URL地址

https://www.ygdy8.net/html/gndy/dyzz/index.html

查看网页是否为静态网页(与静态相对的是动态网页)

怎么查看是否为静态网页?我们可以ctrl+f搜索一下想要爬取的数据,如果查询到数据了,就暂时判定是静态的。但如果没有查询到我们想要的数据,且看到一堆堆的css和js文件,则这个网页可能是动态网页。

打开网页源代码,ctrl+f搜索关键字【攀登者】:

嗯,查询到了数据,该网页应该是静态的。

爬取目标

电影名称(在一级页面中),以及点开电影详情链接后,该电影的下载地址(在二级页面中)。

一级页面中需要爬取的电影名称:

二级页面中需要爬取的下载地址:

这里所谓的二级页面,是相对于一级页面而言的。也就是从一级页面中链接出来的页面。这样说,可能不够形象。举个例子,比如打开淘宝,淘宝首页就是一级页面,点击首页中的一个分类【零食】,所弹出来的网页,就是二级页面。

查找URL规律

同样我们进行翻页操作,检查一下不同页面的URL:

第2页:https://www.ygdy8.net/html/gndy/dyzz/list_23_2.html

第3页:https://www.ygdy8.net/html/gndy/dyzz/list_23_3.html

由此我们可以判断第k页的URL地址为:https://www.ygdy8.net/html/gndy/dyzz/list_23_k.html

我们再右键点击【检查】,查看《攀登者》电影的名称以及详情超链接部分的HTML结构:

我们可以观察HTML页面结构,通过正则表达式,得到含有下载链接的二级页面。

在含有下载链接的二级页面中,同样先查看网页源代码,判断网页是否为静态。

打开网页源代码,ctrl+f搜索关键字【磁力】:

查询到了数据,二级网页也是静态的。

我们观察HTML页面结构,同样可以通过正则表达式得到电影下载链接。

正则表达式

打开一级页面的审查元素,我们发现每个电影名称和其详情链接均在一个<table>标签中:

打开电影《攀登者》的<table>标签,仔细观察其结构和参数值:

为了避免每个<table>标签内的结构不一致,我们在检查一下电影《绝地战警:疾速追击》的结构和参数值:

不错,两部电影的HTML结构和参数很一致,由此可以推断,我们要爬取的电影名称和其详情链接的HTLM结构基本一致。

注意,此时我们提取到的电影详情链接/html/gndy/dyzz/20200401/59854.html貌似没有加上域名,所以,在我们之后敲代码时,要在详情链接前加上域名https://www.ygdy8.net

这时,我们可以将其中一个电影<table>标签内的页面源代码copy下来,仔细观察规律,并在编辑器中编写正则表达式。

正则表达式:

<table width="100%".*?<td height="26".*?<a href="(.*?)".*?>.*?(《.*?)</a>

打开二级页面的页面源代码:

正则表达式:

<td style="WORD-WRAP:.*?>.*?>(.*?)</a>

我们先在mysql中先创建一个新的数据表filmheaven,方便之后要把爬取的数据存进去:

python代码:

import pymysql
from urllib import request, parse
import time
import re
import random
#导入自定义模块
from my_user_agent_list import user_agent



class FilmHeaven:
    def __init__(self):
        self.url = 'https://www.ygdy8.net/html/gndy/dyzz/list_23_{}.html'
        self.user_agent = user_agent
        self.page = 1
        self.db = pymysql.connect(host = '127.0.0.1',
                     port = 3306,
                     user = 'root',
                     password = '19970928',
                     database = 'datacup',
                     charset = 'utf8')
        self.cur = self.db.cursor()
        
    
    #获取html页面
    def get_page(self, url):
        headers = {'User-Agent': random.choice(self.user_agent)}
        #print(headers['User-Agent'])
        req = request.Request(url, headers = headers)
        res = request.urlopen(req)
        html = res.read().decode('gbk', 'ignore')
        return html
    
    #解析提取数据(将1级和2级页面中所有数据一次性拿到)
    def parse_page(self, html):
        regex01 = '<table width="100%".*?<td height="26".*?<a href="(.*?)".*?>.*?(《.*?)</a>'

        #先解析一级页面
        pattern = re.compile(regex01, re.S)
        #film_list = [('电影详情链接', '名称')]
        film_list = pattern.findall(html)
        
        data_list = []
        for link, name in film_list:
            film_name = name.strip()
            film_link = 'https://www.ygdy8.net'+ link.strip()
            download_link = self.parse_two_page(film_link)
            data_list.append((film_name, download_link))
            
            print('电影名称:', film_name)
            #print('下载链接:', download_link)
        sql = 'insert into filmheaven(name, download_link) \
                 values(%s, %s);'
        try:
            self.cur.executemany(sql, data_list)
            self.db.commit()
        except Exception as e:
            self.db.rollback()
            print('错误信息:', e)
        
    def parse_two_page(self, url):
        regex02 =  '<td style="WORD-WRAP:.*?>.*?>(.*?)</a>'
        html = self.get_page(url)
        pattern = re.compile(regex02, re.S)
        download_link = pattern.findall(html)[0]
        return download_link
        
        
        
        #通过电影链接后,获取二级页面的html,再获取下载链接
    
    def main(self):
        for page in range(1, 3):
            url = self.url.format(page)
            one_html = self.get_page(url)
            self.parse_page(one_html)
            print('第%d页爬取完成' % self.page)
            self.page += 1
            time.sleep(random.randint(1, 3))
        self.cur.close()
        self.db.close()
    
if __name__ == '__main__':
    #获取开始的时间戳
    start = time.time()
    spider = FilmHeaven()
    spider.main()
    #获取结束的时间戳
    end = time.time()
    
    print('执行时间:%.2f' % (end-start))
    

备注:如果在decode()解码时遇到编码错误,就把utf-8/gbk/gb2312/gb18030都试一遍,如果都不行!!!注意!这时,就在decode()中加一个参数: ‘ignore’,直接忽略这个编码错误,也就是当做没有看见某些无法识别的字符,继续向后面执行。

控制台输出:

电影名称: 《攀登者》BD国语中英双字
电影名称: 《绝地战警:疾速追击》HD中英双字幕
电影名称: 《小妇人》BD中英双字幕
电影名称: 《生态箱》BD中英双字幕
电影名称: 《多力特的奇幻冒险》BD中英双字幕
电影名称: 《隐形人/隐身人》BD中英双字幕
电影名称: 《狩猎/猎逃生死战》BD中英双字幕
电影名称: 《中国机长》BD国语中英双字
电影名称: 《猛禽小队和哈莉·奎茵》BD中英双字幕
电影名称: 《饥饿站台》BD中英双字幕
电影名称: 《朱迪与潘趣》BD中英双字幕
电影名称: 《音乐家》HD国语中英双字
电影名称: 《偶像/权力杀机》BD韩语中字
电影名称: 《银行家》BD中英双字幕
电影名称: 《大赢家》HD国语中英双字
电影名称: 《刺猬索尼克》BD中英双字幕
电影名称: 《正义的慈悲》BD中英双字幕
电影名称: 《雷米奇遇记》BD国法双语中字
电影名称: 《星球大战9:天行者崛起》BD国英双语双字
电影名称: 《不义之战/辣警霸王花2》BD国粤双语中字
电影名称: 《不义之战/辣警霸王花2》BD国粤双语中字
电影名称: 《星球大战9:天行者崛起》BD中英双字幕
电影名称: 《变身特工》BD国英双语双字
电影名称: 《绑灵》BD国粤双语中字
电影名称: 《误杀》HD国语中英双字
第1页爬取完成
电影名称: 《白头山》BD韩语中字
电影名称: 《南山的部长们》BD韩语中字
电影名称: 《哪吒之魔童降世》BD国语中英双字
电影名称: 《小妇人》HD中英双字幕
电影名称: 《逃离比勒陀利亚》BD中英双字幕
电影名称: 《1917:逆战救兵》BD中英双字幕
电影名称: 《漫画威龙之大话特务》BD韩语中字
电影名称: 《斯宾塞的机密任务》BD中英双字幕
电影名称: 《与我跳舞》BD日语中字
电影名称: 《帕瓦罗蒂》BD中英双字幕
电影名称: 《失踪》BD国粤双语中字
电影名称: 《哈莉·奎因:猛禽小队》HD韩版中英双字
电影名称: 《理查德·朱维尔的哀歌》BD中英双字幕
电影名称: 《南方车站的聚会》HD国语中字
电影名称: 《隐秘的生活》BD中英双字幕
电影名称: 《航海王:狂热行动/海贼王:狂热行动》BD日语中字
电影名称: 《勇敢者游戏2:再战巅峰》BD国英双语双字
电影名称: 《系统破坏者》BD中英双字幕
电影名称: 《最后一搏》BD中英双字幕
电影名称: 《幼女战记剧场版》BD日语中字
电影名称: 《纽约的一个雨天》BD中英双字幕
电影名称: 《利刃出鞘》BD国英双语双字
电影名称: 《半路枪手/腰间持枪》BD中英双字幕
电影名称: 《尼帕病毒》BD中字
电影名称: 《原钻》BD中英双字幕
第2页爬取完成
执行时间:109.34

查看mysql中filmheaven数据表的情况:

 select * from filmheaven;

mysql输出:

不错50条数据都被导入了。

我们再查询name字段中包含【日语中字】的记录:

select * from filmheaven where name like "%日语中字%";

mysql输出:

Perfect!

发布了141 篇原创文章 · 获赞 24 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/m0_37422217/article/details/105282498