爬虫基础知识+豆瓣电影实战

news2024/11/22 21:48:45

什么是爬虫

        简单来说,爬虫就是获取网页并提取和保存信息的自动化程序,爬虫能够自动请求网页,并将所需要的数据抓取下来。通过对抓取的数据进行处理,从而提取出有价值的信息进行存储使用。
为什么用Python做爬虫
        首先您应该明确,不止 Python 这一种语言可以做爬虫,诸如 Java、C/C++、PHP 都可以用来写爬虫程序,但是相比较而言 Python 做爬虫是最简单的。下面对它们的优劣势做简单对比:
        Java 也经常用来写爬虫程序,但是 Java 语言本身很笨重,代码量很大,因此它对于初学者而言,入门的门槛较高;C/C++ 运行效率虽然很高,但是学习和开发成本高。写一个小型的爬虫程序就可能花费很长的时间,PHP:对多线程、异步支持不是很好,并发处理能力较弱。
        而 Python 语言,其语法优美、代码简洁、开发效率高、支持多个爬虫模块,比如 urllib、requests、Bs4、lxml 等。Python 的请求模块和解析模块丰富成熟,并且还提供了强大的 Scrapy 框架,让编写爬虫程序变得更为简单。因此使用 Python 编写爬虫程序是个非常不错的选择。

编写爬虫注意事项

爬虫是一把双刃剑,它给我们带来便利的同时,也给网络安全带来了隐患。有些不法分子利用爬虫在网络上非法搜集网民信息,或者利用爬虫恶意攻击他人网站,从而导致网站瘫痪的严重后果。关于爬虫的如何合法使用,推荐阅读《中华人民共和国网络安全法》。

因此大家在使用爬虫的时候,要自觉遵守国家法律法规,不要非法获取他人信息,或者做一些危害他人网站的事情。

编写爬虫的流程

       爬虫程序与其他程序不同,它的的思维逻辑一般都是相似的,所以无需我们在逻辑方面花费大量的时间。下面对 Python 编写爬虫程序的流程做简单地说明:
        先由 requests 模块的 get() 方法打开 URL 得到网页 HTML 对象。
        使用浏览器打开网页源代码分析网页结构以及元素节点。
        通过解析库(lxml、BeautifulSoup)或则正则表达式提取数据。
        存储数据到本地磁盘或数据库。

        当然也不局限于上述一种流程。编写爬虫程序,需要您具备较好的 Python 编程功底,这样在编写的过程中您才会得心应手。爬虫程序需要尽量伪装成人访问网站的样子,而非机器访问,否则就会被网站的反爬策略限制,甚至直接封杀 IP,相关知识会在后续内容介绍。
        爬虫程序之所以可以抓取数据,是因为爬虫能够对网页进行分析,并在网页中提取出想要的数据。在学习 Python 爬虫模块前,我们有必要先熟悉网页的基本结构,这是编写爬虫程序的必备知识。
        如果您熟悉前端语言,那么您可以轻松地掌握本节知识。
        网页一般由三部分组成,分别是 HTML(超文本标记语言)、CSS(层叠样式表)和 JavaScript(简称“JS”动态脚本语言),它们三者在网页中分别承担着不同的任务。
        HTML 负责定义网页的内容
        CSS 负责描述网页的布局
        JavaScript 负责网页的行为
接下来我们来一起简单了解一下网页的基础知识。

网页基础知识

网页结构

HTML

        HTML 是网页的基本结构,它相当于人体的骨骼结构。网页中同时带有“<”、“>”符号的都属于 HTML标签。常见的 HTML 标签如下所示:

<!DOCTYPE html> 声明为 HTML5 文档
<html>..</html> 是网页的根元素
<head>..</head> 元素包含了文档的元(meta)数据,如 <meta charset="utf-8"> 定义网页编码格式
为 utf-8。
<title>..<title> 元素描述了文档的标题
<body>..</body> 表示用户可见的内容
<div>..</div> 表示框架
<p>..</p> 表示段落
<ul>..</ul> 定义无序列表
<ol>..</ol>定义有序列表
<li>..</li>表示列表项
<img src="" alt="">表示图片
<h1>..</h1>表示标题
<a href="">..</a>表示超链接

编写如下代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>跟拉拉学编程</title></head>
<body><a href="www.youbafu.com">点击访问</a>
<h1>跟拉拉学Python</h1>
<h2>Python爬虫</h2>
<div><p>认识网页结构</p>
    <ul>
        <li>HTML</li>
        <li>CSS</li>
    </ul>
</div>
</body>
</html>

运行结果如下图所示:

CSS

CSS 表示层叠样式表,其编写方法有三种,分别是行内样式内嵌样式外联样式CSS 代码演示如 下:

<!DOCTYPE html>
<html>
    <head>
        <!-- 内嵌样式 -->
    <style type="text/css"> body{ background-color:yellow; }
p{ font-size: 30px; color: springgreen; } </style>
    <meta charset="utf-8">
    <title>跟拉拉学编程</title>
    </head>
    <body>
        <!-- h1标签使用了行内样式 -->
        <h1 style="color: blue;">跟拉拉学Python</h1>
        <a href="www.youbafu.com">点击访问</a>
        <h2>Python爬虫</h2>
        <div>
            <p>认识网页结构</p>
            <ul>
                <li>HTML</li>
                <li>CSS</li>
            </ul>
        </div>
    </body>
</html>

运行结果如下图所示:

如上图所示内嵌样式通过 style 标签书写样式表:

<style type="text/css"></style>

而行内样式则通过 HTML 元素的 style 属性来书写 CSS 代码。注意,每一个 HTML 元素,都有 styleclassidnametitle 属性。

外联样式表指的是将 CSS 代码单独保存为以 .css 结尾的文件,并使用 引入到所需页面:

<head>

<link rel="stylesheet" type="text/css" href="mystyle.css">
</head>

当样式需要被应用到多个页面的时候,使用外联样式表是最佳的选择。

JavaScript

        JavaScript 负责描述网页的行为,比如,交互的内容和各种特效都可以使用 JavaScript 来实现。当然 可以通过其他方式实现,比如 jQuery、还有一些前端框架( vueReact ),不过它们都是在“JS”的基础上 实现的。

简单示例:

<!DOCTYPE html>
<html> 
    <head>
        <style type="text/css"> 
            body{ background-color: rgb(220, 226, 226); }
        </style>
        <meta charset="utf-8"> 
        <title>
            跟拉拉学编程
        </title> 
    </head>


    <body>
        <h1 style="color: blue;">
            跟拉拉学Python
        </h1> 
        <h2>
            Python爬虫
        </h2> 
        <p>
            点击下方按钮获取当前时间
        </p>
        <button onclick="DisplayDate()">
            点击这里
        </button>
        <p id="time" style="color: red;"> 
        </p>
        <!-- script标签内部编写js代码 -->
        <script>
            function DisplayDate() { 
                document.getElementById("time").innerHTML = Date()
            }
        </script> 
        </div>
    </body> 
</html>

运行结果如下:

        如果用人体来比喻网站结构的话,那么 HTML 是人体的骨架,它定义了人的嘴巴、眼睛、耳朵长在什么位置;CSS 描述了人体的外观细节,比如嘴巴长什么样子,眼睛是双眼皮还是单眼,皮肤是黑色的还是 白色的等;而 JavaScript 则表示人拥有的技能,例如唱歌、打球、游泳等。

        当我们在编写一个爬虫程序前,首先要明确待爬取的页面是静态的,还是动态的,只有确定了页面类 型,才方便后续对网页进行分析和程序编写。对于不同的网页类型,编写爬虫程序时所使用的方法也不尽 相同。

网页形态

静态网页

         静态网页是标准的 HTML 文件,通过 GET 请求方法可以直接获取,文件的扩展名是.html .htm 等,网面中可以包含文本、图像、声音、FLASH 动画、客户端脚本和其他插件程序等。静态网页是网站建设的基础,早期的网站一般都是由静态网页制作的。静态并非静止不动,它也包含一些动画效果,这一点不要误解。

        我们知道,当网站信息量较大的时,网页的生成速度会降低,由于静态网页的内容相对固定,且不需要连接后台数据库,因此响应速度非常快。但静态网页更新比较麻烦,每次更新都需要重新加载整个网页。

        静态网页的数据全部包含在 HTML 中,因此爬虫程序可以直接在 HTML 中提取数据。通过分析静态网页的 URL,并找到 URL查询参数的变化规律,就可以实现页面抓取。与动态网页相比,并且静态网页对搜索引擎更加友好,有利于搜索引擎收录。


动态网页

        动态网页指的是采用了动态网页技术的页面,比如 AJAX(是指一种创建交互式、快速动态网页应用的网页开发技术)、ASP(是一种创建动态交互式网页并建立强大的 web 应用程序)JSP( Java 语言创建动 态网页的技术标准) 等技术,它不需要重新加载整个页面内容,就可以实现网页的局部更新。动态页面使用动态页面技术与服务器进行少量的数据交换,从而实现了网页的异步加载。

        抓取动态网页的过程较为复杂,可以使用前面学习的网页自动化来模拟操作实现数据的爬取。

审查网页元素

        对于一个优秀的爬虫工程师而言,要善于发现网页元素的规律,并且能从中提炼出有效的信息。因此,在动手编写爬虫程序前,必须要对网页元素进行审查。本节将讲解如何使用浏览器审查网页元素。

        浏览器都自带检查元素的功能,不同的浏览器对该功能的叫法不同, 谷歌(Chrome)浏览器称为 ,而 Firefox 则称查看元素,尽管如此,但它们的功却是相同的,本教程推荐使用谷歌(Chrome)浏览 器。

检查百度首页

        下面以检查百度首页为例:首先使用 Chrome 浏览器打开百度,然后在百度首页的空白处点击鼠标右 键(或者按快捷键:F12),在出现的会话框中点击检查,并进行如图所示操作:点击审查元素按钮,然 后将鼠移动至a您想检查的位置,比如百度的输入框,然后单击,此时就会将该位置的代码段显示出来, 如下图所示:

        最后在该代码段处点击右键,在出现的会话框中选择 复制 选项卡,并在二级会话框内选择 复制元 ,如下所示:

<input id="kw" name="wd" class="s    ipt" value="" maxlength="255" autocomplete="off">

        依照上述方法,您可以检查页面内的所有元素。

检查网页结构

        对于爬虫而言,检查网页结构是最为关键的一步,需要对网页进行分析,并找出信息元素的相似性。 下面以 豆瓣电影 Top250 豆瓣电影 Top 250 为例,检查每部影片的 HTML 元素结构。 如下图所示:

第一部影片的html代码段如下所示:

<li>
    <div class="item">
        <div class="pic">
            <em class="">1</em>
            <a href="https://movie.douban.com/subject/1292052/">
                <img width="100" alt="肖申克的救赎"
src="https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp"
class="">
            </a>
        </div>
        <div class="info">
            <div class="hd">
                <a href="https://movie.douban.com/subject/1292052/" class="">
                    <span class="title">肖申克的救赎</span>
                    <span class="title">&nbsp;/&nbsp;The Shawshank
Redemption</span>
                    <span class="other">&nbsp;/&nbsp;月黑高飞(港) / 刺激1995(台)
</span>
                </a>
                <span class="playable">[可播放]</span>
            </div>
            <div class="bd">
                <p class="">
                    导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗
宾斯 Tim Robbins /...<br>
                    1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
                </p>
                <div class="star">
                    <span class="rating5-t"></span>
                    <span class="rating_num" property="v:average">9.7</span>
                    <span property="v:best" content="10.0"></span>
                    <span>2564578人评价</span>
                </div>
                <p class="quote">
                    <span class="inq">希望让人自由。</span>
                </p>
            </div>
        </div>
    </div>
</li>

接下来检查第二部影片的html代码,如下所示

<li>
            <div class="item">
                <div class="pic">
                    <em class="">2</em>
                    <a href="https://movie.douban.com/subject/1291546/">
                        <img width="100" alt="霸王别姬" src="https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2561716440.webp" class="">
                    </a>
                </div>
                <div class="info">
                    <div class="hd">
                        <a href="https://movie.douban.com/subject/1291546/" class="">
                            <span class="title">霸王别姬</span>
                                <span class="other">&nbsp;/&nbsp;再见,我的妾  /  Farewell My Concubine</span>
                        </a>


                            <span class="playable">[可播放]</span>
                    </div>
                    <div class="bd">
                        <p class="">
                            导演: 陈凯歌 Kaige Chen&nbsp;&nbsp;&nbsp;主演: 张国荣 Leslie Cheung / 张丰毅 Fengyi Zha...<br>
                            1993&nbsp;/&nbsp;中国大陆 中国香港&nbsp;/&nbsp;剧情 爱情 同性
                        </p>

                        
                        <div class="star">
                                <span class="rating5-t"></span>
                                <span class="rating_num" property="v:average">9.6</span>
                                <span property="v:best" content="10.0"></span>
                                <span>2260298人评价</span>
                        </div>

                            <p class="quote">
                                <span class="inq">风华绝代。</span>
                            </p>
                    </div>
                </div>
            </div>
        </li>

经过对比发现,除了每部影片的信息不同之外,它们的 HTML 结构是相同的,比如每部影片都使用<div class="item"></div> 标签包裹起来。这里我们只检查了两部影片,如果在实际编写时,同学们可 以多检查几部,从而确定它们的 HTML 结构是相同的。

提示:通过检查网页结构,然后发现规律,这是编写爬虫程序最为重要的一步。

豆瓣电影实战

以豆瓣电影Top250为例,我们使用上节课学过的正则表达式,结合分析网页元素来爬取电影的简单信 息并存储到Excel中,或者存储为json文件。

同学们再来一起看看每部影片的html代码元素结构:

<li>
            <div class="item">
                <div class="pic">
                    <em class="">1</em>
                    <a href="https://movie.douban.com/subject/1292052/">
                        <img width="100" alt="肖申克的救赎" src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp" class="">
                    </a>
                </div>
                <div class="info">
                    <div class="hd">
                        <a href="https://movie.douban.com/subject/1292052/" class="">
                            <span class="title">肖申克的救赎</span>
                                    <span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>
                                <span class="other">&nbsp;/&nbsp;月黑高飞(港)  /  刺激1995(台)</span>
                        </a>


                            <span class="playable">[可播放]</span>
                    </div>
                    <div class="bd">
                        <p class="">
                            导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>
                            1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
                        </p>

                        
                        <div class="star">
                                <span class="rating5-t"></span>
                                <span class="rating_num" property="v:average">9.7</span>
                                <span property="v:best" content="10.0"></span>
                                <span>3060501人评价</span>
                        </div>

                            <p class="quote">
                                <span class="inq">希望让人自由。</span>
                            </p>
                    </div>
                </div>
            </div>
        </li>

        这里假设我们要爬取影片的:电影名、电影别名、导演和演员信息、发行时间、地区、类别、推荐 度、评分、评论数、简介信息,我们可以编写对应的正则表达式,将每部影片的需要信息匹配出来,正则表达式如下所示:

# 正则表达式 匹配规则

pattern = re.compile('<li>.*?"title">(.*?)<' +
'.*?"title">(.*?)<.*?"other">(.*?)<' +

'.*?"bd".*?p class="">(.*?)</p>' + # 注意class后面有=""

'.*?"star".*?rating(.*?)-t' +
'.*?"v:average">(.*?)<' +
'.*?<span>(\d+)' +

代码中用到请求模块 requests pandas 库,需要先安装,在终端(Terminal)里输入:

pip install requests

pip install pandas

import json
import os.path
import pandas as pandas
import requests
import re
import csv
# 设置请求头: 模拟浏览器
headers = {
    'Host': 'movie.douban.com',
    'Origin': 'movie.douban.com',
    'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Mobile Safari/537.36',
}
# 正则表达式 匹配规则
pattern = re.compile('<li>.*?"title">(.*?)<' +
    '.*?"title">(.*?)<.*?"other">(.*?)<' +
    '.*?"bd".*?p class="">(.*?)</p>' + # 注意class后面有=""
    '.*?"star".*?rating(.*?)-t' +
    '.*?"v:average">(.*?)<' +
    '.*?<span>(\d+)人' +
    '.*?inq">(.*?)<.*?</li>', re.S)
def get_films(pages=5):
    films = []
    for i in range(pages):
        url = 'https://movie.douban.com/top250?start={}&filter='.format(i * 25)
        text = requests.get(url, headers=headers).text
        for item in re.findall(pattern, text):
            print(item)
            m_info = item[3].replace('&nbsp;', '').strip().split('<br>\n')
            film = {
                '电影名': item[0],
                '别名': item[1].replace('&nbsp;', '').replace(' ', '').strip() +
                    item[2].replace('&nbsp;', '').replace(' ', '').strip(),
                '导演和演员': m_info[0],
                '发行时间': m_info[1].split('/')[0].strip(),
                '地区': m_info[1].split('/')[1].strip(),
                '类别': m_info[1].split('/')[2].strip(),
                '推荐度': '.'.join(list(item[4])),
                '评分': item[5],
                '评论数': item[6],
                '简介': item[7]
            }
            films.append(film)
    return films

def write_cvs(data):
    with open(r'data/re_films.csv', 'w', encoding='utf-8') as f:
        w = csv.DictWriter(f, fieldnames=data[0].keys())
        w.writeheader()
        w.writerows(data)

def write_excel(data):
    pdfile = pandas.DataFrame(data)
    pdfile.to_excel(r'data/re_films.xlsx', sheet_name="豆瓣电影")

def write_json(data):
    s = json.dumps(data, indent=4, ensure_ascii=False)
    with open(r'data/re_films.json', 'w', encoding='utf-8') as f:
        f.write(s)

def start():
    data = list(get_films(1))
    if not os.path.exists('data'):
        os.mkdir('data')
    write_json(data)
    # write_excel(data)
    # write_cvs(data)

if __name__ == '__main__':
    start()
'推荐度': '.'.join(list(item[4]))

这段代码将 `item[4]` 的每个字符用 `'.'` 连接起来。具体步骤如下:

1. **`list(item[4])`**: 将 `item[4]` 转换为字符列表,其中每个字符都是列表的一个元素。
2. **`'.'.join(...)`**: 将字符列表中的每个字符用 `'.'` 连接起来,生成一个新的字符串。

### 示例

假设 `item[4]` 是 `'hello'`,则:

1. **`list(item[4])`**: `['h', 'e', 'l', 'l', 'o']`
2. **`'.'.join(['h', 'e', 'l', 'l', 'o'])`**: `'h.e.l.l.o'`

最终结果是字符之间用 `'.'` 连接的字符串。

m_info = item[3].replace('&nbsp;', '').strip().split('<br>\n')

这段代码对 item[3] 进行了一系列字符串处理操作:

  1. replace('&nbsp;', ''): 替换字符串中的 &nbsp; 为一个空字符串(即删除所有 &nbsp;)。
  2. strip(): 去除字符串开头和结尾的空白字符(如空格、换行)。
  3. split('<br>\n'): 按 <br>\n 进行分割,返回一个列表,列表中的每个元素是按此分隔符分割出来的子串。

这整个过程将 item[3] 中的 HTML 特殊字符和换行符处理后,拆分成一个子串列表。

pdfile.to_excel(r'data/re_films.xlsx', sheet_name="豆瓣电影")

这段代码将 `pdfile` 数据框(DataFrame)保存为一个 Excel 文件。具体操作如下:

- **`to_excel(...)`**: 这是 Pandas 数据框的一个方法,用于将数据框写入 Excel 文件。
- **`r'data/re_films.xlsx'`**: 指定 Excel 文件的路径和文件名。`r` 表示原始字符串,避免转义字符问题。
- **`sheet_name="豆瓣电影"`**: 指定在 Excel 文件中保存数据的工作表名称为 "豆瓣电影"。

### 示例

如果 `pdfile` 是一个数据框,这段代码会将其保存到名为 `re_films.xlsx` 的 Excel 文件中,并在该文件中创建一个名为 "豆瓣电影" 的工作表。

def write_cvs(data):
    with open(r'data/re_films.csv', 'w', encoding='utf-8') as f:
        w = csv.DictWriter(f, fieldnames=data[0].keys())
        w.writeheader()
        w.writerows(data)
  1. import csv: 引入 csv 模块,这个模块提供了用于读写 CSV 文件的工具。

  2. def write_cvs(data):: 定义一个名为 write_cvs 的函数,接受一个参数 data,该参数应是一个包含字典的列表。

  3. with open(r'data/re_films.csv', 'w', encoding='utf-8') as f::

    • open(r'data/re_films.csv', 'w', encoding='utf-8'): 打开一个名为 re_films.csv 的文件,如果文件不存在会创建它。'w' 模式表示写入模式,会清空文件中原有的内容。encoding='utf-8' 指定使用 UTF-8 编码。
    • as f:: 将打开的文件对象赋给变量 f,并在 with 语句块结束后自动关闭文件。
  4. w = csv.DictWriter(f, fieldnames=data[0].keys()):

    • csv.DictWriter(f, fieldnames=data[0].keys()): 创建一个 DictWriter 对象,用于将字典数据写入 CSV 文件。fieldnames 参数指定 CSV 文件的列名,这里使用 data[0].keys() 来获取第一个字典的键作为列名。
  5. w.writeheader(): 写入 CSV 文件的表头,表头由 fieldnames 指定的列名组成。

  6. w.writerows(data): 将 data 中的所有字典写入 CSV 文件。data 应该是一个字典列表,每个字典表示一行数据。

课程总结

        本节课正式进入了爬虫的内容,学习巩固了爬虫的一些基础知识,同时还学习了静态网页的相关基础 知识,毕竟爬虫的本质是对网页元素进行分析处理,只有对相关的基础知识牢固掌握了,写起爬虫来才会 更加轻松自如,最后结合正则表达式对豆瓣电影Top250进行了实战爬取。

课后习题

编程题

根据豆瓣电影实战的源码,利用openpyxl库编写write_excel2()函数,并将爬取到的前3页数据利用该函数保存到 data/re_films2.xlsx 中,保存格式如下图:

 

import openpyxl
from openpyxl import Workbook
import json
import os.path
import pandas as pandas
import requests
import re
import csv
# 设置请求头: 模拟浏览器
headers = {
    'Host': 'movie.douban.com',
    'Origin': 'movie.douban.com',
    'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Mobile Safari/537.36',
}
# 正则表达式 匹配规则
pattern = re.compile('<li>.*?"title">(.*?)<' +
    '.*?"title">(.*?)<.*?"other">(.*?)<' +
    '.*?"bd".*?p class="">(.*?)</p>' + # 注意class后面有=""
    '.*?"star".*?rating(.*?)-t' +
    '.*?"v:average">(.*?)<' +
    '.*?<span>(\d+)人' +
    '.*?inq">(.*?)<.*?</li>', re.S)
def get_films(pages=3):
    films = []
    for i in range(pages):
        url = 'https://movie.douban.com/top250?start={}&filter='.format(i * 25)
        text = requests.get(url, headers=headers).text
        for item in re.findall(pattern, text):
            print(item)
            m_info = item[3].replace('&nbsp;', '').strip().split('<br>\n')
            film = {
                '电影名': item[0],
                '别名': item[1].replace('&nbsp;', '').replace(' ', '').strip() +
                    item[2].replace('&nbsp;', '').replace(' ', '').strip(),
                '导演和演员': m_info[0],
                '发行时间': m_info[1].split('/')[0].strip(),
                '地区': m_info[1].split('/')[1].strip(),
                '类别': m_info[1].split('/')[2].strip(),
                '推荐度': '.'.join(list(item[4])),
                '评分': item[5],
                '评论数': item[6],
                '简介': item[7]
            }
            films.append(film)
    return films

def write_excel2(data):
    # 创建一个工作簿
    wb = Workbook()
    ws = wb.active
    ws.title = "豆瓣电影"

    # 写入表头
    columns = ['电影名', '别名', '导演和演员', '发行时间', '地区', '类别', '推荐度', '评分', '评论数', '简介']
    ws.append(columns)

    # 写入数据
    for film in data:
        ws.append([
            film.get('电影名', ''),
            film.get('别名', ''),
            film.get('导演和演员', ''),
            film.get('发行时间', ''),
            film.get('地区', ''),
            film.get('类别', ''),
            film.get('推荐度', ''),
            film.get('评分', ''),
            film.get('评论数', ''),
            film.get('简介', '')
        ])

    # 保存到文件
    wb.save('data/re_films2.xlsx')

def start():
    data = list(get_films(3))  # 获取前3页数据
    if not os.path.exists('data'):
        os.mkdir('data')
    write_excel2(data)

if __name__ == '__main__':
    start()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2114548.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python 中使用tkinter构建一个图片的剪切器-附源码

由于项目需要&#xff0c;需要构建一个间的软件&#xff0c;方便查看图片的剪切的位置&#xff0c;并对其中的图像进行分析&#xff0c;实现如下的功能 简单的UI加载图片剪切图片显示剪切后的图片 针对图片的内容进行识别 图片质量分析 前端的具体代码如下&#xff0c; 有需…

5.8 切换保护模式(5)

1 首先测试 了&#xff0c; 之前的代码 是 没有问题的&#xff0c;确实会 停在 汇编处。 1 首先是 设置 除了 CS 之外的寄存器 进入 32为模式 //为了使除了 cs 之外的 段选择寄存器也进入 32位模式。mov $16, %ax // 16为数据段选择子mov %ax, %dsmov %ax, %ssmov %ax, %esmov…

axure动态面板

最近转管理岗了&#xff0c;作为项目负责人&#xff0c;需要常常与客户交流沟通&#xff0c;这时候画原型的能力就是不可或缺的本领之一了&#xff0c;关于axure可能很多it行业者都不是很陌生&#xff0c;简单的功能呢大家就自行去摸索&#xff0c;我们这次从动态面板开始讲起。…

C语言进阶版第8课—指针(2)

文章目录 1. 数组名的理解2. 指针访问数组3. 一维数组传参本质4. 冒泡排序5. 二级指针6. 指针数组7. 指针数组模拟二维数组 1. 数组名的理解 sizeof&#xff08;数组名&#xff09;— 这里的数组名代表整个数组&#xff0c;计算的也是整个数组的大小&数组名 — 这里的数组名…

adb devices找不到设备

重新启动ADB服务。在命令行窗口中输入adb kill-server&#xff0c;然后再输入adb start-server&#xff0c;重新启动ADB服务 再重启插入手机连入电脑的线&#xff0c;再次启动开发模式。 在在命令行窗口中输入adb version

【大数据】深入浅出Hadoop,干货满满

【大数据】深入浅出Hadoop 文章脉络 Hadoop HDFS MapReduce YARN Hadoop集群硬件架构 假设现在有一个PB级别的数据库表要处理。 在单机情况下&#xff0c;只能升级你的内存、磁盘、CPU&#xff0c;那么这台机器就会变成 “超算”&#xff0c;成本太高&#xff0c;商业公司肯…

Java基础知识回顾-匿名内部类

文章目录 知识学习实现案例第一步、父类定义方法第二步、子类中定义匿名内部类第三步、执行方法 最近在复习Java知识点的时候&#xff0c;在看匿名内部类&#xff0c;记录下来&#xff0c;方便备查。 知识学习 匿名内部类&#xff0c;即一种特殊的局部内部类&#xff0c;不需要…

java opencv no opencv_java490 in java.library.path

java使用opencv处理图片&#xff0c;idea运行程序&#xff0c;报错异常信息&#xff1a; Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java490 in java.library.path: /Users/carter/Library/Java/Extensions:/Library/Java/Extensions:…

Canvas Confetti - 免费开源的五彩纸屑飞舞特效的 JS 库,多用于在网页上实现欢乐庆祝的场景

今天看科技周刊看到的一个酷炫的动效库&#xff0c;使用简单&#xff0c;视觉效果很好&#xff0c;推荐给大家。 Canvas Confetti 是一个基于 JavaScript 的特效动画库&#xff0c;可以在网页界面上轻松地实现五彩纸屑飞舞的庆祝场景特效。这个特效库封装了几种酷炫的特效&…

Linux系统之实现dhcp功能(Implementation of DHCP Function in Linux System)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

tabBar设置底部菜单以及选项iconfont图标

1.tabBar设置底部菜单 在官网里面可以了解到tabBar组件的一些知识和注意点&#xff1a; 需要给页面设置一个底部导航的话可以在pages.json里面设置一个tabBar标签&#xff0c;在其里面设置pagePath和text属性。 可以看的pagePath是跳转的地址&#xff0c;text是下面导航的文字…

string详解

Golang详解string 文章目录 Golang详解stringGolang中为什么string是只读的&#xff1f;stirng和[]byte的转化原理[]byte转string一定需要内存拷贝吗&#xff1f;字符串拼接性能测试 Golang中为什么string是只读的&#xff1f; 在Go语言中&#xff0c;string其实就是一个结构体…

SSM项目使用AOP技术进行日志记录

本步骤只记录完成切面所需的必要代码 本人开发中遇到的问题&#xff1a; 切面一直切不进去&#xff0c;最后发现需要在springMVC的核心配置文件中中开启注解驱动才可以&#xff0c;只在spring的核心配置文件中开启是不会在web项目中生效的。 之后按照下面的代码进行配置&…

【Python篇】PyQt5 超详细教程——由入门到精通(中篇二)

文章目录 PyQt5超详细教程前言第7部分&#xff1a;生成图表与数据可视化7.1 matplotlib 与 PyQt5 的结合7.2 在 PyQt5 中嵌入 matplotlib 图表示例 1&#xff1a;嵌入简单的 matplotlib 图表代码详解&#xff1a; 7.3 动态生成图表示例 2&#xff1a;动态更新图表代码详解&…

jmeter之TPS计算公式

需求&#xff1a; 如何确定环境当中的TPS指标 PV:&#xff08;Page View&#xff09;即页面访问量&#xff0c;每打开一次页面PV计数1&#xff0c;刷新页面也是。PV只统计页面访问次 数。 UV(Unique Visitor),唯一访问用户数&#xff0c;用来衡量真实访问网站的用户数量。 一般…

在亚马逊云科技上利用Graviton4代芯片构建高性能Java应用(上篇)

简介 在AI迅猛发展的时代&#xff0c;芯片算力对于模型性能起到了至关重要的作用。一款能够同时兼具高性能和低成本的芯片&#xff0c;能够帮助开发者快速构建性能稳定的生成式AI应用&#xff0c;同时降低开发成本。今天小李哥将介绍亚马逊推出的4代高性能计算处理器Gravition…

【Python 千题 —— 算法篇】无重复字符最长子段

Python 千题持续更新中 …… 脑图地址 &#x1f449;&#xff1a;⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目背景 在编程过程中&#xff0c;处理字符串的任务时常遇到&#xff0c;其中一个经典问题是查找无重复字符的最长子串。这在很多应用场景中…

Linux网络测试和故障排查命令

文章目录 ping 命令常用选项&#xff1a;使用示例&#xff1a;域名解析和 IP 地址响应数据停止 ping 命令统计数据延迟统计 traceroute 命令常用选项&#xff1a;使用示例&#xff1a;命令执行&#xff1a;路由节点详情&#xff1a; mtr 命令使用示例&#xff1a;使用结果详解输…

【持续更新】Adoobe Acroobat Pro DC 2024 (v24.3.20054)最新修改版

Adoobe Acroobat Pro DC 拥有智能工具&#xff0c;为您的沟通能力增添更多力量。使用包含丰富媒体元素的PDF文件进行创建与编辑&#xff0c;更加安全地分享信息&#xff0c;并且更高效地收集反馈意见。这款先进的软件程序是商务专业人士的理想选择&#xff0c;能够创建、合并、…

jmeter之ForEach控制器使用

ForEach控制器作用&#xff1a; 一般和用户自定义变量或者正则表达式提取器配合使用&#xff0c;读取返回结果中一系列相关的变量值&#xff0c;该控制器下的取样器都会被执行一次或多次&#xff0c;每次读取不同的变量值(类似python当中的for语句,用来遍历操作) 本节代码已上…