爬虫项目(12):正则、多线程抓取腾讯动漫,Flask展示数据

文章目录

书籍推荐

如果你对Python网络爬虫感兴趣,强烈推荐你阅读《Python网络爬虫入门到实战》。这本书详细介绍了Python网络爬虫的基础知识和高级技巧,是每位爬虫开发者的必读之作。详细介绍见👉: 《Python网络爬虫入门到实战》 书籍介绍

正则抓取腾讯动漫数据

csharp 复制代码
import requests
import re
import threading
from queue import Queue


def format_html(html):
    li_pattern = re.compile('<li class="ret-search-item clearfix">[\s\S]+?</li>')

    title_pattern = re.compile('title="(.*?)"')
    img_src_pattern = re.compile('data-original="(.*?)"')
    update_pattern = re.compile('<span class="mod-cover-list-text">(.*?)</span>')
    tags_pattern = re.compile('<span href="/Comic/all/theme/.*?" target="_blank">(.*?)</span>')
    popularity_pattern = re.compile('<span>人气:<em>(.*?)</em></span>')

    items = li_pattern.findall(html)
    for item in items:
        title = title_pattern.search(item).group(1)
        img_src = img_src_pattern.search(item).group(1)
        update_info = update_pattern.search(item).group(1)
        tags = tags_pattern.findall(item)
        popularity = popularity_pattern.search(item).group(1)

        data_queue.put(f'{title},{img_src},{update_info},{"#".join(tags)},{popularity}\n')


def run(index):
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
        }
        response = requests.get(f"https://ac.qq.com/Comic/index/page/{index}", headers=headers)
        html = response.text
        format_html(html)
    except Exception as e:
        print(f"Error occurred while processing page {index}: {e}")
    finally:
        semaphore.release()


if __name__ == "__main__":
    data_queue = Queue()
    semaphore = threading.BoundedSemaphore(5)
    lst_record_threads = []

    for index in range(1, 3):
        print(f"正在抓取{index}")
        semaphore.acquire()
        t = threading.Thread(target=run, args=(index,))
        t.start()
        lst_record_threads.append(t)

    for rt in lst_record_threads:
        rt.join()

    with open("./qq_comic_data.csv", "a+", encoding="gbk") as f:
        while not data_queue.empty():
            f.write(data_queue.get())

    print("数据爬取完毕")

Flask展示数据

上面能够实现爬取数据,但是我希望展示在前端。

main.py代码如下:

csharp 复制代码
# coding= gbk
from flask import Flask, render_template
import csv

app = Flask(__name__)


def read_data_from_csv():
    with open("qq_comic_data.csv", "r", encoding="utf-8") as f:
        reader = csv.reader(f)
        data = list(reader)[1:]  # 跳过标题行

        # 统一转换人气数据为浮点数(单位:亿)
        for row in data:
            popularity = row[4]
            if '亿' in popularity:
                row[4] = float(popularity.replace('亿', ''))
            elif '万' in popularity:
                row[4] = float(popularity.replace('万', '')) / 10000  # 将万转换为亿

        # 按人气排序并保留前10条记录
        data.sort(key=lambda x: x[4], reverse=True)
        return data[:10]

@app.route('/')
def index():
    comics = read_data_from_csv()
    return render_template('index.html', comics=comics)

if __name__ == '__main__':
    app.run(debug=True)

templates/index.html如下:

csharp 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>漫画信息</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            color: #333;
            line-height: 1.6;
            padding: 20px;
        }
        .container {
            width: 80%;
            margin: auto;
            overflow: hidden;
        }
        h1 {
            text-align: center;
            color: #333;
        }
        .comic {
            background: #fff;
            margin-bottom: 20px;
            padding: 15px;
            border-radius: 10px;
            box-shadow: 0 5px 10px rgba(0,0,0,0.1);
        }
        .comic h2 {
            margin-top: 0;
        }
        .comic p {
            line-height: 1.25;
        }
        .comic:nth-child(even) {
            background: #f9f9f9;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>人气前10的漫画</h1>
        {% for comic in comics %}
            <div class="comic">
                <h2>{{ comic[0] }}</h2>
                <p><strong>更新信息:</strong>{{ comic[2] }}</p>
                <p><strong>类型:</strong>{{ comic[3] }}</p>
                <p><strong>人气:</strong>{{ comic[4] }}</p>
            </div>
        {% endfor %}
    </div>
</body>
</html>

效果如下:

相关推荐
chao_7891 小时前
二分查找篇——搜索旋转排序数组【LeetCode】一次二分查找
数据结构·python·算法·leetcode·二分查找
烛阴1 小时前
Python装饰器解除:如何让被装饰的函数重获自由?
前端·python
noravinsc2 小时前
django 一个表中包括id和parentid,如何通过parentid找到全部父爷id
python·django·sqlite
ajassi20002 小时前
开源 python 应用 开发(三)python语法介绍
linux·python·开源·自动化
沉默媛2 小时前
如何安装python以及jupyter notebook
开发语言·python·jupyter
Deng9452013143 小时前
基于Python的旅游数据可视化应用
python·numpy·pandas·旅游·数据可视化技术
2401_878624793 小时前
pytorch 自动微分
人工智能·pytorch·python·机器学习
胖达不服输3 小时前
「日拱一码」021 机器学习——特征工程
人工智能·python·机器学习·特征工程
screenCui4 小时前
macOS运行python程序遇libiomp5.dylib库冲突错误解决方案
开发语言·python·macos
小眼睛羊羊5 小时前
pyinstaller打包paddleocr
python