爬取央视热榜并存储到MongoDB

1. 环境准备

在开始之前,确保你已经安装了以下Python库:

python 复制代码
pip install requests pymongo

2. 爬取网页内容

首先,我们需要爬取央视热榜的网页内容。通过requests.get()方法,我们可以获取网页的HTML内容,并通过re.findall()方法来提取我们感兴趣的部分。

python 复制代码
import requests
import re

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (HTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
}
url = 'https://tv.cctv.com/top/index.shtml?spm=C28340.PdNvWY0LYxCP.EtmP5mypaGE4.11'
res = requests.get(url, headers=headers)
con = res.content.decode("utf8")

在这一步中,我们访问了央视的热榜页面,并将网页内容解码为UTF-8格式。

3. 解析数据

我们使用正则表达式来提取每个榜单的具体内容。通过re.findall()方法,我们可以从HTML中提取出特定的榜单数据。

python 复制代码
datas = re.findall(r'<ul>.*?</ul>', con, re.S)

4. 解析每个榜单的数据

我们将热榜分为几个类别,如热播榜、动画片、电视剧、纪录片和特别节目。分别对每个类别的数据进行解析:

python 复制代码
result = {
    "热播榜": {"name": "热播榜", "items": []},
    "动画片": {"name": "动画片", "items": []},
    "电视剧": {"name": "电视剧", "items": []},
    "纪录片": {"name": "纪录片", "items": []},
    "特别节目": {"name": "特别节目", "items": []}
}

# 热播榜
items = re.findall(
    r'<li.*?lazy="(.*?)".*?<div class="text"><a href=".*?" target="_blank">(.*?)</a>'
    r'</div>.*?<div class="column"><i class="icon_l"></i><a href=".*?" target="_blank">(.*?)</a>'
    r'<i class="icon_r"></i></div>.*?</li>',
    datas[1], re.S)
for item in items:
    result["热播榜"]["items"].append({
        "img": item[0],
        "title": item[1],
        "category": item[2]
    })

# 动画片
items = re.findall(
    r'<li.*?lazy="(.*?)" width="188" height="250"></a>.*?<span class="number"><i class="icon_l">'
    r'</i><i class="txt">(.*?)</i><i class="icon_r"></i></span>.*?</div>.*?'
    r'<a class="cover" href=".*?" target="_blank">.*?</a>.*?<div class="text">'
    r'<a href=".*?" target="_blank">(.*?)</a></div>.*?<p><a href=".*?" target="_blank">(.*?)</a></p>.*?</li>'
    , datas[2], re.S
)
for item in items:
    result["动画片"]["items"].append({
        "img": item[0],
        "title": item[2],
        "category": item[1],
        "synopsis": item[3]
    })

# 电视剧
items = re.findall(
    r'<li.*?lazy="(.*?)" width="188" height="250"></a>.*?<span class="number">'
    r'<i class="icon_l"></i><i class="txt">(.*?)</i><i class="icon_r"></i></span>.*?</div>.*?'
    r'<a class="cover" href=".*?" target="_blank">.*?</a>.*?<div class="text"><a href=".*?" target="_blank">(.*?)</a>'
    r'</div>.*?<p><a href=".*?" target="_blank">(.*?)</a></p>.*?</li>',
    datas[3], re.S
)
for item in items:
    result["电视剧"]["items"].append({
        "img": item[0],
        "title": item[2],
        "episode": item[1],
        "synopsis": item[3]
    })

# 纪录片
items = re.findall(
    r'<li.*?lazy="(.*?)" width="188" height="250"></a>.*?<span class="number">'
    r'<i class="icon_l"></i><i class="txt">(.*?)</i><i class="icon_r"></i>'
    r'</span>.*?</div>.*?<a class="cover" href=".*?" target="_blank">.*?</a>.*?<div class="text">'
    r'<a href=".*?" target="_blank">(.*?)</a></div>.*?<p><a href=".*?" target="_blank">(.*?)</a></p>.*?</li>',
    datas[4], re.S
)
for item in items:
    result["纪录片"]["items"].append({
        "img": item[0],
        "title": item[2],
        "category": item[1],
        "synopsis": item[3]
    })

# 特别节目
items = re.findall(
    r'<li.*?lazy="(.*?)" width="188" height="250"></a>.*?<span class="number">'
    r'<i class="icon_l"></i><i class="txt">(.*?)</i><i class="icon_r"></i></span>.*?</div>.*?'
    r'<a class="cover" href=".*?" target="_blank">.*?</a>.*?<div class="text"><a href=".*?" target="_blank">(.*?)</a>'
    r'</div>.*?<p><a href=".*?" target="_blank">(.*?)</a></p>.*?</li>',
    datas[5], re.S
)
for item in items:
    result["特别节目"]["items"].append({
        "img": item[0],
        "title": item[2],
        "tv": item[1],
        "synopsis": item[3]
    })

在这段代码中,我们通过正则表达式分别提取了每个榜单的数据。每个榜单的数据结构可能略有不同,因此我们为每个榜单编写了相应的解析规则。

数据字段说明:
  • img: 每个节目对应的封面图片链接。
  • title: 节目的标题。
  • category: 节目的种类(如:动画片、电视剧等)。
  • episode: 电视剧的集数(仅电视剧榜单有此字段)。
  • synopsis: 节目的简要介绍。
  • tv: 电视台信息(仅特别节目榜单有此字段)。

5. 存储数据到MongoDB

解析完成后,我们将获取的数据存储到MongoDB中。首先,我们需要连接到MongoDB,然后将解析结果插入到相应的集合中。

python 复制代码
import pymongo

client = pymongo.MongoClient()
db = client.get_default_database("cctv")
collection = db.get_collection("top")
collection.insert_one(result)
client.close()

上述代码连接到本地的MongoDB实例,并将数据插入到名为cctv的数据库中的top集合中。最后,关闭数据库连接。

6. 总结

通过以上步骤,我们成功地爬取了央视热榜的数据,并将其存储到MongoDB中。这种方法可以用来定期更新数据,构建自己的数据分析系统,或者为其他应用提供数据支持。

代码:
python 复制代码
import re

import pymongo
import requests

headers = {
    # 请求工具标识
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (HTML, like Gecko) "
                  "Chrome/127.0.0.0 Safari/537.36"
}
url = 'https://tv.cctv.com/top/index.shtml?spm=C28340.PdNvWY0LYxCP.EtmP5mypaGE4.11'
res = requests.get(url, headers=headers)
con = res.content.decode("utf8")
datas = re.findall(r'<ul>.*?</ul>', con, re.S)
result = {
    "热播榜": {
        "name": "热播榜",
        "items": []
    },
    "动画片": {
        "name": "动画片",
        "items": []
    },
    "电视剧": {
        "name": "电视剧",
        "items": []
    },
    "纪录片": {
        "name": "纪录片",
        "items": []
    },
    "特别节目": {
        "name": "特别节目",
        "items": []
    }
}
# print(datas[1])
items = re.findall(
    r'<li.*?lazy="(.*?)".*?<div class="text"><a href=".*?" target="_blank">(.*?)</a>'
    r'</div>.*?<div class="column"><i class="icon_l"></i><a href=".*?" target="_blank">(.*?)</a>'
    r'<i class="icon_r"></i></div>.*?</li>',
    datas[1], re.S)
for item in items:
    # print(item)
    result["热播榜"]["items"].append({
        "img": item[0],
        "title": item[1],
        "category": item[2]
    })
    # pass
# print(datas[2])
items = re.findall(
    r'<li.*?lazy="(.*?)" width="188" height="250"></a>.*?<span class="number"><i class="icon_l">'
    r'</i><i class="txt">(.*?)</i><i class="icon_r"></i></span>.*?</div>.*?'
    r'<a class="cover" href=".*?" target="_blank">.*?</a>.*?<div class="text">'
    r'<a href=".*?" target="_blank">(.*?)</a></div>.*?<p><a href=".*?" target="_blank">(.*?)</a></p>.*?</li>'
    , datas[2], re.S
)
for item in items:
    # print(item)
    result["动画片"]["items"].append({
        "img": item[0],
        "title": item[2],
        "category": item[1],
        "synopsis": item[3]
    })
    # pass
# print(datas[3])
items = re.findall(
    r'<li.*?lazy="(.*?)" width="188" height="250"></a>.*?<span class="number">'
    r'<i class="icon_l"></i><i class="txt">(.*?)</i><i class="icon_r"></i></span>.*?</div>.*?'
    r'<a class="cover" href=".*?" target="_blank">.*?</a>.*?<div class="text"><a href=".*?" target="_blank">(.*?)</a>'
    r'</div>.*?<p><a href=".*?" target="_blank">(.*?)</a></p>.*?</li>'
    , datas[3], re.S
)
for item in items:
    # print(item)
    result["电视剧"]["items"].append({
        "img": item[0],
        "title": item[2],
        "episode": item[1],
        "synopsis": item[3]
    })
    # pass
# print(datas[4])
items = re.findall(
    r'<li.*?lazy="(.*?)" width="188" height="250"></a>.*?<span class="number">'
    r'<i class="icon_l"></i><i class="txt">(.*?)</i><i class="icon_r"></i>'
    r'</span>.*?</div>.*?<a class="cover" href=".*?" target="_blank">.*?</a>.*?<div class="text">'
    r'<a href=".*?" target="_blank">(.*?)</a></div>.*?<p><a href=".*?" target="_blank">(.*?)</a></p>.*?</li>'
    , datas[4], re.S
)
for item in items:
    # print(item)
    result["纪录片"]["items"].append({
        "img": item[0],
        "title": item[2],
        "category": item[1],
        "synopsis": item[3]
    })
    # pass
# print(datas[5])
items = re.findall(
    r'<li.*?lazy="(.*?)" width="188" height="250"></a>.*?<span class="number">'
    r'<i class="icon_l"></i><i class="txt">(.*?)</i><i class="icon_r"></i></span>.*?</div>.*?'
    r'<a class="cover" href=".*?" target="_blank">.*?</a>.*?<div class="text"><a href=".*?" target="_blank">(.*?)</a>'
    r'</div>.*?<p><a href=".*?" target="_blank">(.*?)</a></p>.*?</li>'
    , datas[5], re.S
)
for item in items:
    # print(item)
    result["特别节目"]["items"].append({
        "img": item[0],
        "title": item[2],
        "tv": item[1],
        "synopsis": item[3]
    })
    # pass
# print(result)
client = pymongo.MongoClient()
db = client.get_default_database("cctv")
collection = db.get_collection("top")
collection.insert_one(result)
client.close()
爬取数据:

7. 提示

  • 在实际应用中,如果需要处理大量数据或频繁请求网页,建议添加异常处理和请求延时,以避免对服务器造成过大压力。
  • 如果网页结构发生变化,正则表达式可能需要相应调整。
  • 遵守 robots.txt :在爬取任何网站之前,检查其 robots.txt 文件,确保你的爬虫行为符合网站的爬虫协议。

希望这篇博客对你有所帮助,祝你在数据爬取和存储的学习过程中取得进展!

相关推荐
ROCKY_8174 小时前
Mysql复习(二)
数据库·mysql·oracle
Dovir多多5 小时前
Python数据处理——re库与pydantic的使用总结与实战,处理采集到的思科ASA防火墙设备信息
网络·python·计算机网络·安全·网络安全·数据分析
问道飞鱼7 小时前
【知识科普】认识正则表达式
数据库·mysql·正则表达式
HaiFan.7 小时前
SpringBoot 事务
java·数据库·spring boot·sql·mysql
水根LP497 小时前
linux系统上SQLPLUS的重“大”发现
数据库·oracle
沐霜枫叶7 小时前
解决pycharm无法识别miniconda
ide·python·pycharm
途途途途7 小时前
精选9个自动化任务的Python脚本精选
数据库·python·自动化
蓝染然8 小时前
jax踩坑指南——人类早期驯服jax实录
python
许野平8 小时前
Rust: enum 和 i32 的区别和互换
python·算法·rust·enum·i32
问道飞鱼8 小时前
【Python知识】Python进阶-什么是装饰器?
开发语言·python·装饰器