首页 > 编程语言 >使用Python和BeautifulSoup进行网页爬虫与数据采集

使用Python和BeautifulSoup进行网页爬虫与数据采集

时间:2024-10-18 17:21:25浏览次数:3  
标签:rating title Python people BeautifulSoup 爬虫 movies 数据

目录

一、什么是网页爬虫?

1.1 网页爬虫的应用场景

二、爬虫的基本流程

三、准备工作

四、实战:抓取豆瓣电影Top 250

4.1 发送请求

4.2 解析页面

4.3 数据存储

五、应对反爬虫技术

5.1 使用代理

5.2 模拟浏览器行为

六、爬虫的扩展与优化

6.1 处理分页

6.2 多线程爬取

6.3 动态内容解析

6.4 处理异常与容错

七、高级主题:分布式爬虫

7.1 Scrapy简介

7.2 Scrapy的基本使用

7.3 启用分布式爬虫

八、数据清洗与存储

8.1 数据清洗

8.2 数据存储

8.2.1 使用SQLite进行本地存储

8.2.2 使用MySQL进行持久化存储

8.3 数据分析与可视化

九、反爬机制应对与法律合规

9.1 绕过反爬措施

9.1.1 使用代理IP

9.1.2 伪造请求头

9.1.3 使用验证码识别技术

9.1.4 控制请求频率

总结


在互联网时代,数据是最宝贵的资源之一,而获取数据的能力则是数据分析、人工智能等领域的基础技能。本文将深入探讨如何使用Python和BeautifulSoup库进行网页爬虫与数据采集。我们将从基本概念入手,逐步展示如何搭建一个简单而功能强大的网页爬虫,并通过具体的代码实例引导您完成数据采集任务。

一、什么是网页爬虫?

网页爬虫(Web Scraper)是一种自动化程序,用于浏览网页并提取所需数据。通过模拟用户在浏览器中的行为,爬虫可以自动访问网站、解析HTML页面,并将指定的数据提取出来保存到本地。

1.1 网页爬虫的应用场景
  • 数据分析:获取特定领域的海量数据进行分析。
  • 价格监控:自动监控电商平台的商品价格。
  • 内容聚合:从多个新闻网站抓取文章并集中展示。

二、爬虫的基本流程

一个典型的网页爬虫通常包括以下步骤:

  1. 发送请求:使用Python的requests库发送HTTP请求获取网页的HTML内容。
  2. 解析页面:使用BeautifulSoup解析HTML页面,定位并提取所需的数据。
  3. 数据存储:将提取的数据保存到本地,如CSV、数据库等。

接下来我们通过一个实例详细演示如何实现这些步骤。

三、准备工作

在开始编写爬虫之前,需要安装所需的Python库。我们将使用requests来发送HTTP请求,使用BeautifulSoup来解析HTML页面。

pip install requests
pip install beautifulsoup4

四、实战:抓取豆瓣电影Top 250

我们将构建一个简单的爬虫,抓取豆瓣电影Top 250页面的数据,包括电影名称、评分和评论人数。

4.1 发送请求

首先,我们需要向豆瓣电影Top 250页面发送HTTP请求,并获取页面的HTML内容。

import requests

url = "https://movie.douban.com/top250"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
}

response = requests.get(url, headers=headers)

if response.status_code == 200:
    html = response.text
else:
    print("Failed to retrieve the webpage")

在这个代码片段中,我们使用requests.get发送GET请求,并通过response.text获取页面的HTML内容。注意,为了避免被网站识别为爬虫,我们添加了一个User-Agent头部。

4.2 解析页面

获取HTML内容后,接下来我们使用BeautifulSoup解析页面,并提取出我们感兴趣的数据——电影名称、评分和评论人数。

from bs4 import BeautifulSoup

soup = BeautifulSoup(html, "html.parser")
movies = []

for item in soup.find_all("div", class_="item"):
    title = item.find("span", class_="title").get_text()
    rating = item.find("span", class_="rating_num").get_text()
    people = item.find("div", class_="star").find_all("span")[-1].get_text()
    
    movies.append({
        "title": title,
        "rating": rating,
        "people": people
    })

在这个代码片段中,我们使用BeautifulSoup创建一个解析对象,并通过soup.find_all方法找到所有电影条目。然后,通过查找每个条目中的特定HTML元素提取出电影的名称、评分和评论人数。

4.3 数据存储

为了便于后续分析,我们将抓取的数据保存到CSV文件中。

import csv

with open("douban_top250.csv", "w", newline="", encoding="utf-8") as csvfile:
    fieldnames = ["title", "rating", "people"]
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    
    writer.writeheader()
    for movie in movies:
        writer.writerow(movie)

此代码段将提取的数据写入CSV文件douban_top250.csv,每一行代表一部电影的相关信息。

五、应对反爬虫技术

在实际操作中,许多网站会采取反爬虫措施来阻止自动化程序的访问。常见的反爬虫技术包括IP封禁、CAPTCHA验证、动态内容加载等。为了应对这些挑战,我们可以采取以下措施:

5.1 使用代理

通过使用代理服务器,可以隐藏真实的IP地址,从而绕过网站的IP封禁。

proxies = {
    "http": "http://your_proxy_ip:port",
    "https": "https://your_proxy_ip:port"
}

response = requests.get(url, headers=headers, proxies=proxies)
5.2 模拟浏览器行为

通过使用像Selenium这样的工具,您可以模拟浏览器的行为,包括处理JavaScript动态内容、执行页面滚动等。

pip install selenium
from selenium import webdriver

driver = webdriver.Chrome()
driver.get(url)

html = driver.page_source
driver.quit()

六、爬虫的扩展与优化

在上一节中,我们构建了一个基础的爬虫来抓取豆瓣电影Top 250的数据。然而,实际项目中爬虫的需求往往更加复杂。我们可能需要处理分页、多线程爬取、动态内容解析等问题。接下来,我们将探讨如何扩展和优化爬虫,使其能够应对更复杂的场景。

6.1 处理分页

许多网站的数据会分布在多个分页中,例如,豆瓣电影Top 250页面实际上有10页内容。如果我们只抓取一页的数据,那么获取的信息将是不完整的。因此,处理分页是爬虫的重要功能。

我们可以通过分析网页URL来找到分页的规律。例如,豆瓣电影Top 250的分页URL为:

https://movie.douban.com/top250?start=0
https://movie.douban.com/top250?start=25
https://movie.douban.com/top250?start=50
...

每一页的URL中,start参数按25递增。因此,我们可以通过循环构建分页URL,并抓取每一页的数据。

movies = []

for i in range(0, 250, 25):
    url = f"https://movie.douban.com/top250?start={i}"
    response = requests.get(url, headers=headers)
    
    if response.status_code == 200:
        soup = BeautifulSoup(response.text, "html.parser")
        
        for item in soup.find_all("div", class_="item"):
            title = item.find("span", class_="title").get_text()
            rating = item.find("span", class_="rating_num").get_text()
            people = item.find("div", class_="star").find_all("span")[-1].get_text()
            
            movies.append({
                "title": title,
                "rating": rating,
                "people": people
            })

这个代码段展示了如何通过循环遍历分页URL,抓取所有页的数据并存储在一个列表中。

6.2 多线程爬取

随着爬取规模的增大,单线程爬虫的效率可能会变得不够高。为了提升爬虫的性能,我们可以引入多线程技术,使爬虫能够并发地处理多个页面。

Python中的concurrent.futures模块提供了便捷的多线程支持。我们可以利用ThreadPoolExecutor来实现多线程爬取。

from concurrent.futures import ThreadPoolExecutor

def fetch_page(url):
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        soup = BeautifulSoup(response.text, "html.parser")
        page_movies = []
        for item in soup.find_all("div", class_="item"):
            title = item.find("span", class_="title").get_text()
            rating = item.find("span", class_="rating_num").get_text()
            people = item.find("div", class_="star").find_all("span")[-1].get_text()
            
            page_movies.append({
                "title": title,
                "rating": rating,
                "people": people
            })
        return page_movies
    return []

urls = [f"https://movie.douban.com/top250?start={i}" for i in range(0, 250, 25)]
movies = []

with ThreadPoolExecutor(max_workers=5) as executor:
    results = executor.map(fetch_page, urls)
    for result in results:
        movies.extend(result)

在这个代码片段中,我们定义了一个fetch_page函数用于抓取单个页面的数据。然后,通过ThreadPoolExecutor实现并发爬取,max_workers=5表示最多同时运行5个线程。

6.3 动态内容解析

许多现代网站使用JavaScript加载动态内容,这使得传统的基于HTML解析的爬虫无法直接获取所需数据。在这种情况下,我们可以采用Selenium或Playwright等工具模拟浏览器行为,以获取动态加载的数据。

以下是使用Selenium抓取动态内容的基本流程:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager

# 设置Chrome浏览器
options = webdriver.ChromeOptions()
options.add_argument("--headless")  # 无头模式
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)

# 打开目标网页
driver.get("https://example.com/dynamic_page")

# 等待动态内容加载
driver.implicitly_wait(10)  # 等待10秒

# 获取动态内容
content = driver.find_element(By.ID, "dynamic_content").text

# 关闭浏览器
driver.quit()

在这个示例中,我们使用Selenium打开一个动态网页,并通过implicitly_wait等待JavaScript加载完成。然后,通过find_element获取动态内容并提取数据。Selenium支持多种浏览器,使用它可以应对大多数复杂的动态网页。

6.4 处理异常与容错

爬虫在实际运行过程中,难免会遇到各种异常,如网络超时、页面结构变化等。为了保证爬虫的健壮性,我们需要加入异常处理机制,并确保在出现问题时能够进行适当的处理或重试。

import time

def fetch_page_with_retry(url, retries=3):
    try:
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()  # 如果请求返回错误状态码,触发异常
        return response.text
    except requests.exceptions.RequestException as e:
        if retries > 0:
            print(f"Error fetching {url}: {e}. Retrying...")
            time.sleep(2)
            return fetch_page_with_retry(url, retries - 1)
        else:
            print(f"Failed to fetch {url} after multiple retries.")
            return None

在这个函数中,fetch_page_with_retry实现了一个简单的重试机制。如果请求失败,它会等待一段时间后重试,直到达到最大重试次数为止。

七、高级主题:分布式爬虫

当数据规模巨大,单台机器的性能无法满足需求时,可以考虑使用分布式爬虫。分布式爬虫可以利用多台机器并行爬取,极大提高效率。Scrapy是Python中一个功能强大的爬虫框架,支持分布式爬虫,并且集成了许多高级功能。

7.1 Scrapy简介

Scrapy是一个高层次的Python爬虫框架,用于抓取网站并从页面中提取结构化数据。它支持分布式爬取、异步I/O、并发处理等功能,非常适合构建大型数据采集项目。

7.2 Scrapy的基本使用

首先,我们需要安装Scrapy:

pip install scrapy

接下来,创建一个Scrapy项目:

scrapy startproject myspider

这将生成一个包含多个文件和目录的项目结构。myspider/spiders目录是放置爬虫代码的地方。我们可以在其中创建一个简单的爬虫来抓取豆瓣电影Top 250。

import scrapy

class DoubanSpider(scrapy.Spider):
    name = "douban"
    start_urls = ["https://movie.douban.com/top250"]

    def parse(self, response):
        for item in response.css("div.item"):
            yield {
                "title": item.css("span.title::text").get(),
                "rating": item.css("span.rating_num::text").get(),
                "people": item.css("div.star span::text")[-1].get(),
            }

        next_page = response.css("span.next a::attr(href)").get()
        if next_page is not None:
            yield response.follow(next_page, self.parse)

在这个代码片段中,我们定义了一个DoubanSpider类,并实现了parse方法,用于解析页面并提取数据。Scrapy的一个特点是它可以自动处理分页,通过response.follow方法抓取下一页的数据。

7.3 启用分布式爬虫

Scrapy支持通过分布式爬虫进行大规模数据采集。可以结合Scrapy-Redis库实现分布式功能,该库提供了基于Redis的调度器和数据存储机制,使得爬虫可以跨多台机器协调工作。

安装Scrapy-Redis:

pip install scrapy-redis

在Scrapy项目中启用Scrapy-Redis,只需要进行一些简单的配置修改。编辑settings.py文件:

# 启用Redis调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

# 启用Redis管道
ITEM_PIPELINES = {
    'scrapy_redis.pipelines.RedisPipeline': 300,
}

# 配置Redis连接
REDIS_URL = 'redis://localhost:6379'

通过上述配置,爬虫将自动利用Redis进行去重和调度,从而实现分布式爬取。

八、数据清洗与存储

在我们爬取到数据后,下一步是对数据进行清洗和存储。这一步在数据采集项目中至关重要,因为原始数据往往包含冗余、不完整或格式不统一的部分。通过数据清洗,我们可以确保数据的质量,以便后续的分析和处理。此外,将数据存储在合适的数据库中,便于高效的查询和管理。

8.1 数据清洗

数据清洗的目标是去除无关信息、填补缺失值、规范数据格式等。以我们从豆瓣电影Top 250抓取的数据为例,可能存在一些电影没有评分、评论人数等信息,或者数据格式不符合预期。

以下是一个简单的数据清洗过程,确保我们只保留完整且格式正确的数据。

import re
import pandas as pd

# 假设我们已经抓取到的数据存储在movies列表中
movies = [
    {"title": "肖申克的救赎", "rating": "9.7", "people": "1234567人评价"},
    {"title": "霸王别姬", "rating": "9.6", "people": "987654人评价"},
    {"title": "这个杀手不太冷", "rating": "", "people": "456789人评价"},
    # 更多数据...
]

# 数据清洗
cleaned_movies = []

for movie in movies:
    if movie["rating"] and movie["people"]:
        # 清洗评论人数数据,去除“人评价”字符,转化为整数
        people = int(re.sub(r"\D", "", movie["people"]))
        # 清洗并格式化数据
        cleaned_movies.append({
            "title": movie["title"],
            "rating": float(movie["rating"]),
            "people": people
        })

# 转换为DataFrame便于后续处理
df = pd.DataFrame(cleaned_movies)
print(df.head())

在上面的代码中,我们使用正则表达式去除“人评价”中的非数字字符,并将其转换为整数。数据清洗的细节取决于实际项目中的需求和数据质量。在复杂的项目中,数据清洗可能涉及到更多的逻辑,比如填补缺失值、标准化日期格式、处理重复数据等。

8.2 数据存储

数据清洗完成后,我们需要将数据存储到合适的数据库中。常见的选择包括关系型数据库(如MySQL、PostgreSQL)、NoSQL数据库(如MongoDB)以及分布式数据存储系统(如Hadoop、Cassandra)。

8.2.1 使用SQLite进行本地存储

SQLite是一种轻量级的嵌入式数据库,非常适合小规模数据的本地存储。它无需服务器配置,使用简单且性能较好。

我们可以使用sqlite3库将清洗后的数据存储到SQLite数据库中。

import sqlite3

# 连接SQLite数据库(如果数据库不存在,则会自动创建)
conn = sqlite3.connect("movies.db")
cursor = conn.cursor()

# 创建表
cursor.execute('''
    CREATE TABLE IF NOT EXISTS movies (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        rating REAL NOT NULL,
        people INTEGER NOT NULL
    )
''')

# 插入数据
for movie in cleaned_movies:
    cursor.execute('''
        INSERT INTO movies (title, rating, people)
        VALUES (?, ?, ?)
    ''', (movie["title"], movie["rating"], movie["people"]))

# 提交事务并关闭连接
conn.commit()
conn.close()

这个代码段展示了如何创建一个SQLite数据库和表,并将数据插入到表中。SQLite非常适合开发和测试阶段的快速迭代。

8.2.2 使用MySQL进行持久化存储

对于生产环境或大规模数据存储,MySQL等关系型数据库是更常见的选择。我们可以使用pymysql库与MYSQL数据库进行交互。

import pymysql

# 连接MySQL数据库
conn = pymysql.connect(
    host="localhost",
    user="your_username",
    password="your_password",
    database="your_database"
)
cursor = conn.cursor()

# 创建表
cursor.execute('''
    CREATE TABLE IF NOT EXISTS movies (
        id INT AUTO_INCREMENT PRIMARY KEY,
        title VARCHAR(255) NOT NULL,
        rating FLOAT NOT NULL,
        people INT NOT NULL
    )
''')

# 插入数据
for movie in cleaned_movies:
    cursor.execute('''
        INSERT INTO movies (title, rating, people)
        VALUES (%s, %s, %s)
    ''', (movie["title"], movie["rating"], movie["people"]))

# 提交事务并关闭连接
conn.commit()
conn.close()

使用MySQL数据库的好处在于其强大的查询和管理功能,尤其是在数据量较大的情况下,MySQL能够提供更高的性能和稳定性。

8.3 数据分析与可视化

一旦数据被存储,我们可以利用Python的强大数据分析和可视化工具(如Pandas、Matplotlib、Seaborn)对数据进行进一步的分析和展示。

例如,我们可以分析豆瓣电影的评分分布、用户评价数与评分的相关性等。

import matplotlib.pyplot as plt
import seaborn as sns

# 数据加载(假设已存储在DataFrame中)
df = pd.DataFrame(cleaned_movies)

# 评分分布直方图
plt.figure(figsize=(10, 6))
sns.histplot(df["rating"], kde=True, bins=10)
plt.title("豆瓣电影Top 250评分分布")
plt.xlabel("评分")
plt.ylabel("电影数量")
plt.show()

# 评分与评价人数的关系
plt.figure(figsize=(10, 6))
sns.scatterplot(x="rating", y="people", data=df)
plt.title("评分与评价人数的关系")
plt.xlabel("评分")
plt.ylabel("评价人数")
plt.show()

这些可视化图表能够帮助我们更直观地理解和分析数据,为后续的决策提供有力支持。

九、反爬机制应对与法律合规

在进行网页爬虫时,我们不可避免地会遇到网站的反爬机制。常见的反爬措施包括验证码、IP封禁、请求频率限制等。如何有效地绕过这些机制,同时保证爬虫行为的合法合规,是爬虫开发中的重要议题。

9.1 绕过反爬措施

网站通常会通过以下几种方式来阻止爬虫的访问:

  1. IP封禁:检测到同一IP的频繁请求后,网站会临时或永久封禁该IP。
  2. User-Agent检测:通过分析请求头中的User-Agent,判断请求是否来自于真实的浏览器。
  3. 验证码:在访问某些敏感页面时,要求用户输入验证码以证明自己是人类。
  4. 请求频率限制:限制单位时间内同一IP或用户的请求次数。

我们可以通过以下方法来应对这些反爬措施:

9.1.1 使用代理IP

通过使用代理IP,我们可以在请求时伪装成来自不同IP的用户,从而避免被封禁。许多代理IP服务商提供高质量的代理IP,适合大规模爬虫使用。

proxies = {
    "http": "http://your_proxy_ip:your_proxy_port",
    "https": "https://your_proxy_ip:your_proxy_port"
}

response = requests.get(url, headers=headers, proxies=proxies)
9.1.2 伪造请求头

伪造请求头中的User-Agent可以使爬虫请求看起来更像是来自真实用户的浏览器。除了User-Agent,我们还可以伪造Referer、Accept-Language等请求头。

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36",
    "Referer": "https://www.example.com",
    "Accept-Language": "en-US,en;q=0.9"
}
response = requests.get(url, headers=headers)
9.1.3 使用验证码识别技术

对于验证码,最简单的方法是人工输入,但这显然不适合大规模爬取。我们可以利用OCR(Optical Character Recognition,光学字符识别)技术来自动识别简单的验证码,或者借助第三方验证码识别服务。

import pytesseract
from PIL import Image

image = Image.open("captcha.png")
captcha_text = pytesseract.image_to_string(image)
print(captcha_text)
9.1.4 控制请求频率

为了避免触发网站的频率限制,我们可以在每次请求之间设置随机的时间间隔,从而模拟真实用户的行为。

import time
import random

for url in urls:
    response = requests.get(url, headers=headers)
    time.sleep(random

.uniform(1, 3))  # 随机等待1到3秒

总结

本文深入探讨了如何使用Python和BeautifulSoup进行网页爬虫与数据采集,涵盖了从基础HTML解析到高级动态内容解析的完整过程。我们介绍了如何应对分页、处理请求异常、并发多线程抓取数据,以及如何使用Selenium处理动态加载内容。进一步,我们探讨了数据清洗与存储的重要性,演示了如何使用SQLite和MySQL进行数据存储,并通过Pandas和可视化工具对数据进行分析。

在面对网站反爬机制时,我们提供了使用代理IP、伪造请求头、验证码识别和控制请求频率等应对措施,并强调了遵守法律与道德规范的重要性。通过本文的学习,读者不仅能够构建一个功能完备的爬虫系统,还能掌握应对实际项目中复杂问题的技巧,为未来的爬虫项目打下坚实的基础。

标签:rating,title,Python,people,BeautifulSoup,爬虫,movies,数据
From: https://blog.csdn.net/qq_20314339/article/details/143058002

相关文章

  • 超简单的婴儿哭声检测实现方案--python版
    超简单的婴儿哭声检测实现方案--python版1.构建项目项目结构└─audio_data##音频文件├─mp3├─test└─wav##训练音频源文件每个目录代表不同的标签,自己定义和随意增加,cry目录存放的是婴儿的哭声├─cry├─non_cry└─other└─get-model.py└─main.py└......
  • gTTS: 强大的Python文本转语音库
    gTTSgTTS简介gTTS(GoogleText-to-Speech)是一个Python库和命令行工具,用于与GoogleTranslate的文本转语音API进行交互。它允许用户将文本转换为语音,并将结果保存为MP3文件或进行进一步的音频处理。gTTS支持多种语言,并提供了丰富的自定义选项,使其成为一个强大而灵活的文本转......
  • Python中的索引和切片
    Python中的索引和切片是比较重要的内容,在数组处理中至关重要。这里对于2种情况做一个甄别。索引单元素索引单元素索引的工作原理与其他标准Python序列完全相同。它是从0开始的,并接受负索引以从数组的末尾进行索引。x=np.arange(10)x[2]2x[-2]8无需将每个维度的索引......
  • 最新毕设-SpringBoot-校园学习交流和资源共享平台-78210(免费领项目)可做计算机毕业设计
    目录1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2系统分析2.1可行性分析2.2系统流程分析2.2.1 数据流程2.2.2 用户登录流程2.3 系统功能分析2.3.1功能性分析2.3.2非功能性分析2.4 系统用例分析2.5本章小结3 系统......
  • 基于网络爬虫技术的中国电动汽车市场分析与可视化系统 毕业设计-附源码02721
    摘要中国电动汽车市场快速发展,政策支持和环保意识提升推动了电动汽车需求增长。基于网络爬虫技术的中国电动汽车市场分析与可视化系统旨在提供全面的电动汽车市场数据分析和直观的可视化展示。系统利用Python进行数据处理和分析,Django构建后端框架,Vue实现前端交互,实现数据的......
  • 基于卷积神经网络的乳腺癌细胞识别系统,resnet50,mobilenet模型【pytorch框架+python源
     更多目标检测和图像分类识别项目可看我主页其他文章功能演示:卷积神经网络,乳腺癌细胞识别系统,resnet50,mobilenet【pytorch框架,python】_哔哩哔哩_bilibili(一)简介基于卷积神经网络的乳腺癌细胞识别系统是在pytorch框架下实现的,这是一个完整的项目,包括代码,数据集,训练好的模......
  • 关于Python AI 编程助手Fitten Code的应用体验以及Python 修改删除 sys.path 路径以实
    一、关于PythonAI编程助手FittenCode的应用体验        AI现在无孔不入,现在都开始进入到编程中了,有一个能适用多种编译器环境的AI编程插件FittenCode。其适配了ViusalStudio,VSCode(本文使用),JetBrains系列(本文使用)以及Vim等多种编译器环境的插件FittenCo......
  • python+flask框架的购书推荐小程序(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容选题背景随着互联网技术的飞速发展,电子商务已成为人们日常生活的重要组成部分,其中在线购书因其便捷性和丰富的选择而备受欢迎。然而,面对海量的图书......
  • python+flask框架的公寓管理系统小程序小程序端28(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容选题背景随着城市化进程的加速,公寓租赁市场日益繁荣,传统的人工管理方式已难以满足高效、便捷的管理需求。关于公寓管理系统的研究,现有研究主要以大......
  • python+flask框架的公安管理系统(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容选题背景公安管理系统作为现代警务工作的重要组成部分,对于提升公安部门的工作效率、加强社会治安管理具有重要意义。目前,国内外关于公安管理系统的......