python爬虫------- Selenium下篇(二十三天)

news2024/9/21 22:53:37

🎈🎈作者主页: 喔的嘛呀🎈🎈
🎈🎈所属专栏:python爬虫学习🎈🎈
✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 

 

目录

十、处理动态内容

十一、处理验证码

十二、模拟登录

十三、跨页面操作

十四、异常处理

十五、数据存储

存储到文件(例如 CSV 文件)

存储到数据库(例如 SQLite)

存储到其他存储介质(例如 MongoDB)

十六、反爬虫策略

十七、性能优化

十八、定时任务:

十九、 与其他库和工具的集成


helllo,兄弟姐妹们!今天我们接着把第二十二天剩下的十个知识点学完(从第十个开始)。

十、处理动态内容

处理动态加载内容的常见方法是通过模拟用户操作来触发页面加载新内容。对于需要滚动页面加载的情况,可以使用 Selenium 的 execute_script 方法来执行 JavaScript 代码,从而实现滚动页面的效果。下面是一个示例代码,演示如何使用 Selenium 模拟滚动页面来加载更多内容:


from selenium import webdriver
import time

# 启动浏览器
driver = webdriver.Chrome()

# 打开网页
driver.get('<https://example.com>')

# 模拟滚动页面
scroll_pause_time = 2  # 每次滚动后等待时间
screen_height = driver.execute_script("return window.screen.height;")   # 获取屏幕高度

i = 1
while True:
    # 记录滚动前页面高度
    last_height = driver.execute_script("return document.body.scrollHeight;")

    # 模拟滚动到页面底部
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

    # 等待页面加载
    time.sleep(scroll_pause_time)

    # 计算新的页面高度
    new_height = driver.execute_script("return document.body.scrollHeight;")

    # 如果新的页面高度和上次相同,则说明已经滚动到底部
    if new_height == last_height:
        break

    # 打印滚动次数
    print(f"Scrolling {i} times")
    i += 1

# 获取页面数据
data = driver.page_source

# 关闭浏览器
driver.quit()

# 处理页面数据,如解析数据等

在这个示例中,我们首先启动 Chrome 浏览器,并打开了一个示例网页。然后,我们通过执行 JavaScript 代码来模拟滚动页面到底部的效果。在每次滚动后,我们等待了2秒钟以确保页面有足够的时间加载新内容。如果页面高度不再增加,说明已经滚动到了页面底部,循环就会结束。最后,我们获取了页面的 HTML 源码,并可以继续处理数据,如解析数据等操作。

请注意,这只是一个简单的示例。实际情况可能会更复杂,具体取决于要爬取的网站和其动态加载数据的机制。

十一、处理验证码

处理网页中的验证码通常需要结合 Selenium 和图像识别技术。下面是一个使用 Selenium 和 pytesseract 库来处理网页中简单验证码的示例:

首先,安装 Pillow、pytesseract 和 pytesseract 库:


pip install Pillow pytesseract selenium

然后,下载并安装 Tesseract OCR,并将其添加到系统路径中。

接下来,使用以下代码示例:


from PIL import Image
import pytesseract
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import requests
from io import BytesIO

# 设置 Tesseract OCR 路径
pytesseract.pytesseract.tesseract_cmd = r'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'

# 启动浏览器
driver = webdriver.Chrome()

# 打开网页
driver.get('<https://example.com>')

# 找到验证码图片元素
captcha_element = driver.find_element(By.XPATH, '//img[@id="captcha-image"]')

# 获取验证码图片的链接
captcha_image_url = captcha_element.get_attribute('src')

# 下载验证码图片
response = requests.get(captcha_image_url)
captcha_image = Image.open(BytesIO(response.content))

# 识别验证码
captcha_text = pytesseract.image_to_string(captcha_image)

# 输入验证码
captcha_input = driver.find_element(By.XPATH, '//input[@id="captcha-input"]')
captcha_input.send_keys(captcha_text)

# 提交表单
submit_button = driver.find_element(By.XPATH, '//button[@id="submit-button"]')
submit_button.click()

# 等待页面加载
time.sleep(2)

# 获取页面数据
data = driver.page_source

# 关闭浏览器
driver.quit()

# 处理页面数据,如解析数据等

在这个示例中,我们首先设置了 Tesseract OCR 的路径。然后,使用 Selenium 打开了一个示例网页,并找到了验证码图片元素。我们通过请求验证码图片的链接,并使用 pytesseract 库识别验证码中的文本。最后,我们将识别结果填写到验证码输入框中,并提交表单。

请注意,这只适用于简单的验证码。对于复杂的验证码,可能需要使用更复杂的技术和工具。

注意:

Tesseract OCR(Optical Character Recognition)是一个开源的光学字符识别引擎,由 Google 开发并维护。它能够将图像中的文字转换为可编辑的文本。Tesseract 能够识别超过100种语言的文字,并且支持许多图像格式。Tesseract 的最新版本是4.x,具有比较高的准确性和性能。

使用 Tesseract OCR 进行文本识别通常涉及以下步骤:

  1. 安装 Tesseract OCR:根据您的操作系统下载并安装 Tesseract OCR。对于 Windows 系统,可以从 GitHub Release 页面下载安装包进行安装。对于 macOS 和 Linux 系统,可以通过包管理器(如 Homebrew 或 apt)安装。

  2. 安装 pytesseract:pytesseract 是一个 Python 模块,用于与 Tesseract OCR 进行交互。您可以使用 pip 安装 pytesseract:

    bashCopy code
    pip install pytesseract
    
    
  3. 使用 pytesseract 进行图像文本识别:下面是一个简单的示例代码,演示如何使用 pytesseract 对图像进行文本识别:

    
    from PIL import Image
    import pytesseract
    
    # 读取图像文件
    image = Image.open('example.png')
    
    # 使用 pytesseract 进行文本识别
    text = pytesseract.image_to_string(image)
    
    # 打印识别结果
    print(text)
    
    

Tesseract OCR 对于特定字体、大小和质量的图像效果可能会有所不同。在实际使用中,我们需要调整图像预处理和 Tesseract 的参数来获得最佳的识别结果。

十二、模拟登录

要使用 Selenium 模拟登录网站并爬取需要登录才能访问的页面,我们可以按照以下步骤进行:

  1. 启动浏览器并打开登录页面。
  2. 填写登录表单,包括用户名和密码。
  3. 点击登录按钮。
  4. 等待登录完成。
  5. 访问需要登录才能访问的页面,提取数据或进行其他操作。

下面是一个示例代码,演示如何使用 Selenium 模拟登录网站并爬取需要登录才能访问的页面:


from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

# 启动浏览器
driver = webdriver.Chrome()

# 打开登录页面
driver.get('<https://example.com/login>')

# 填写用户名和密码
username_input = driver.find_element(By.ID, 'username')
password_input = driver.find_element(By.ID, 'password')

username_input.send_keys('your_username')
password_input.send_keys('your_password')

# 提交登录表单
password_input.send_keys(Keys.RETURN)

# 等待登录完成,这里假设登录成功后会跳转到首页
time.sleep(2)

# 访问需要登录才能访问的页面
driver.get('<https://example.com/protected_page>')

# 提取页面数据或进行其他操作
data_element = driver.find_element(By.XPATH, '//div[@class="data"]')
data = data_element.text
print('Protected Page Data:', data)

# 关闭浏览器
driver.quit()

请注意,在实际使用中,我们需要替换示例中的 '<https://example.com/login''your_username'> 和 'your_password' 为实际的登录页面 URL、用户名和密码。同时,确保我们的行为符合网站的使用条款和规定,以免触发反爬虫措施。

十三、跨页面操作

处理需要跨页面操作的情况通常需要在页面之间进行导航和交互。使用 Selenium 可以模拟用户在网页上的操作,包括点击链接跳转到另一个页面。下面是一个示例代码,演示如何在一个页面点击链接跳转到另一个页面进行数据提取:


from selenium import webdriver
from selenium.webdriver.common.by import By
import time

# 启动浏览器
driver = webdriver.Chrome()

# 打开第一个页面
driver.get('<https://example.com/page1>')

# 点击页面上的链接
link_element = driver.find_element(By.XPATH, '//a[@id="link-to-page2"]')
link_element.click()

# 等待页面加载
time.sleep(2)

# 在第二个页面提取数据
data_element = driver.find_element(By.XPATH, '//div[@id="data-on-page2"]')
data = data_element.text

print('Data on page 2:', data)

# 关闭浏览器
driver.quit()

在这个示例中,我们首先启动了 Chrome 浏览器,并打开了第一个页面。然后,我们找到了第一个页面上的链接元素,并使用 click() 方法点击了该链接。随后,我们等待了2秒钟,以确保第二个页面加载完成。最后,我们找到了第二个页面上的数据元素,并提取了其文本内容。

需要注意的是,实际情况可能更复杂,具体取决于网站的结构和交互方式。在处理跨页面操作时,确保等待页面加载完成并处理可能的异常情况是很重要的。

十四、异常处理

在爬取过程中,可能会出现各种异常情况,如超时、元素未找到等。为了确保爬虫的稳定性和可靠性,需要对这些异常情况进行处理。下面是一个示例代码,演示如何使用 try-except 语句来处理这些异常情况:


from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 启动浏览器
driver = webdriver.Chrome()

try:
    # 设置页面加载超时时间为10秒
    driver.set_page_load_timeout(10)

    # 打开网页
    driver.get('<https://example.com>')

    # 显式等待10秒,直到元素加载完成
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.XPATH, '//div[@id="content"]'))
    )

    # 提取数据
    content_element = driver.find_element(By.XPATH, '//div[@id="content"]')
    content = content_element.text
    print('Content:', content)

except TimeoutException:
    print('页面加载超时')

except NoSuchElementException:
    print('元素未找到')

finally:
    # 关闭浏览器
    driver.quit()

在这个示例中,我们使用了 try-except 语句来捕获可能出现的 TimeoutException(超时异常)和 NoSuchElementException(元素未找到异常)。在 try 代码块中,我们设置了页面加载超时时间为10秒,并使用显式等待来等待页面元素加载完成。如果页面加载超时或元素未找到,则会相应地捕获并处理异常。最后,无论是否发生异常,我们都会在 finally 代码块中关闭浏览器。

通过合理地处理异常情况,可以使爬虫在遇到问题时能够优雅地处理,并继续执行其他操作。

十五、数据存储

提取到的数据存储到文件、数据库或其他存储介质中是网页爬取的重要步骤之一。具体的存储方式取决于您的需求和项目的要求。以下是几种常见的数据存储方式示例:

存储到文件(例如 CSV 文件)


import csv

data = [{'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]

with open('data.csv', mode='w', newline='') as file:
    writer = csv.DictWriter(file, fieldnames=['name', 'age'])
    writer.writeheader()
    for row in data:
        writer.writerow(row)

存储到数据库(例如 SQLite)


import sqlite3

data = [{'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]

conn = sqlite3.connect('data.db')
cursor = conn.cursor()

cursor.execute('''CREATE TABLE IF NOT EXISTS users
              (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)''')

for row in data:
    cursor.execute('INSERT INTO users (name, age) VALUES (?, ?)', (row['name'], row['age']))

conn.commit()
conn.close()

存储到其他存储介质(例如 MongoDB)


from pymongo import MongoClient

data = [{'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]

client = MongoClient('mongodb://localhost:27017/')
db = client['mydatabase']
collection = db['users']

for row in data:
    collection.insert_one(row)

client.close()

这些示例展示了如何将提取到的数据存储到不同的存储介质中。您可以根据项目的需要选择适合的存储方式。

十六、反爬虫策略

反爬虫策略是网站为防止被爬虫程序恶意抓取数据而采取的一系列措施。常见的反爬虫策略包括:

  1. User-Agent检测:网站会检查请求中的 User-Agent 字段,如果发现是爬虫程序常用的 User-Agent,则可能拒绝服务或返回特定响应。
  2. IP地址限制:网站可能会限制同一IP地址的访问频率,过高频率的访问会被视为异常行为。
  3. 验证码:网站可能会在某些操作前要求用户输入验证码,以确认访问者是人类而不是爬虫程序。
  4. 动态加载内容:网站使用JavaScript等技术来动态加载内容,使得只有通过真正执行页面脚本才能获取到完整内容。
  5. 频率限制:限制同一用户或IP地址在一定时间内的请求频率,过高频率的请求会被拒绝。
  6. 页面结构变化:定期改变页面结构,使得爬虫程序难以适应变化而失效。

应对这些反爬虫策略的方法包括:

  1. 设置合理的User-Agent:模拟浏览器行为,避免使用常见的爬虫User-Agent。
  2. 使用代理IP:使用代理IP来隐藏真实IP地址,避免被网站封禁。
  3. 处理验证码:使用验证码识别技术自动处理验证码。
  4. 限制访问频率:设置合理的访问间隔时间,避免过高频率的访问。
  5. 使用随机延迟:在请求之间添加随机延迟,模拟人类操作。
  6. 动态解析页面:使用动态解析技术获取动态加载的内容。
  7. 定期监测网站变化:定期检查网站结构的变化,及时调整爬取策略。
  8. 遵守robots.txt规范:遵守网站的robots.txt文件中的规定,不访问被禁止的页面。

综上所述,应对反爬虫策略需要综合考虑网站的具体情况和采取合适的应对策略。

十七、性能优化

当涉及性能优化时,代码中的优化通常是特定于应用程序和场景的。下面是一些常见的Python爬虫代码优化技巧示例:

(1)减少不必要的等待时间:避免使用固定的等待时间,而是根据需要进行动态等待。示例代码:


from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get("<https://example.com>")

try:
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "myElement"))
    )
finally:
    driver.quit()

(2)合理使用隐式等待:在创建WebDriver实例时设置隐式等待时间,而不是在每个操作中都设置等待时间。示例代码:


from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10) # 设置隐式等待时间为10秒

driver.get("<https://example.com>")
element = driver.find_element(By.ID, "myElement")

(3)使用多线程/异步处理:使用**concurrent.futures**模块进行异步处理。示例代码:


from concurrent.futures import ThreadPoolExecutor
from selenium import webdriver

def scrape(url):
    driver = webdriver.Chrome()
    driver.get(url)
    # 爬取逻辑
    driver.quit()

urls = ['<https://example.com/page1>', '<https://example.com/page2>', '<https://example.com/page3>']

with ThreadPoolExecutor(max_workers=5) as executor:
    executor.map(scrape, urls)

(4)避免重复请求:使用缓存来存储已经爬取过的数据。示例代码:


import requests
import hashlib

cache = {}

def get_data(url):
    if url in cache:
        return cache[url]

    response = requests.get(url)
    data = response.text
    cache[url] = data
    return data

url = '<https://example.com>'
data = get_data(url)

这些示例代码演示了一些常见的Python爬虫代码优化技巧,但实际的优化策略应根据具体的爬虫应用程序和场景进行调整和优化。

十八、定时任务:

要将爬虫任务设置为定时执行,可以使用Python的**schedule库来实现。schedule库可以帮助我们在指定的时间间隔内定期运行任务。以下是一个简单的示例代码,演示如何使用schedule**库来定时执行爬虫任务:


import schedule
import time

def crawl():
    # 在这里编写爬虫逻辑
    print("开始爬取数据...")

# 每小时执行一次爬虫任务
schedule.every().hour.do(crawl)

# 在这里可以设置其他定时任务,如每天、每周等

# 保持程序运行,直到手动终止
while True:
    schedule.run_pending()
    time.sleep(1)

在这个示例中,**crawl函数是我们的爬虫逻辑。使用schedule.every().hour.do(crawl)来设置每小时执行一次爬虫任务。您还可以使用其他schedule.every()**方法来设置其他的定时任务,如每天、每周等。

请注意,为了保持程序持续运行,我们使用了一个**while True循环来不断检查是否有定时任务需要执行,并使用time.sleep(1)**来让程序每秒钟检查一次。这样可以确保定时任务能够按照预期执行。

十九、 与其他库和工具的集成

将Selenium与其他库和工具集成可以实现更强大的功能,比如使用BeautifulSoup解析页面内容、使用pandas处理数据等。以下是一个示例代码,演示了如何将Selenium与BeautifulSoup和pandas集成:

pythonCopy code
from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd

# 启动浏览器
driver = webdriver.Chrome()

# 打开网页
driver.get('<https://example.com>')

# 获取页面源码
html = driver.page_source

# 使用BeautifulSoup解析页面
soup = BeautifulSoup(html, 'html.parser')

# 提取需要的数据
data = []
for item in soup.find_all('div', class_='item'):
    name = item.find('h2').text
    price = item.find('span', class_='price').text
    data.append({'name': name, 'price': price})

# 将数据转换为DataFrame
df = pd.DataFrame(data)

# 关闭浏览器
driver.quit()

# 打印数据
print(df)

在这个示例中,我们首先使用Selenium打开了一个网页,并获取了页面的源码。然后,我们使用BeautifulSoup解析了页面,并提取了需要的数据。最后,我们使用pandas将数据转换为DataFrame,并进行打印输出。这样,就实现了将Selenium与BeautifulSoup和pandas集成的功能。

好了,今天的学习就到这里了,第二十四天会带来几个案例将上面的知识点运用起来。敬请期待!拜拜啦!

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

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

相关文章

11.哀家要长脑子了!

目录 1.453. 最小操作次数使数组元素相等 - 力扣&#xff08;LeetCode&#xff09; 2.665. 非递减数列 - 力扣&#xff08;LeetCode&#xff09; 3. 283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 4. 3114. 替换字符可以得到的最晚时间 - 力扣&#xff08;LeetCode…

构建第一个ArkTS用的资源分类与访问

应用开发过程中&#xff0c;经常需要用到颜色、字体、间距、图片等资源&#xff0c;在不同的设备或配置中&#xff0c;这些资源的值可能不同。 应用资源&#xff1a;借助资源文件能力&#xff0c;开发者在应用中自定义资源&#xff0c;自行管理这些资源在不同的设备或配置中的表…

Redis实现延迟任务的几种方案

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1.前言 2.Redis如何实现延迟任务&#xff1f; 3.代码实现 3.1. 过期键通知事…

【Java】maven的生命周期和概念图

maven的生命周期&#xff1a; 在maven中存在三套"生命周期"&#xff0c;每一套生命周期,相互独立,互不影响的,但是中同一套生命周期里,执行后面的命令会自动先执行前面的命令 CleanLifeCycle&#xff1a;清理的生命周期 clean defaultLifeCycle&#xff1a;默认的…

智能物联网远传冷水表管理系统

智能物联网远传冷水表管理系统是一种基于物联网技术的先进系统&#xff0c;旨在实现对冷水表的远程监测、数据传输和智能化管理。本文将从系统特点、构成以及带来的效益三个方面展开介绍。 系统特点 1.远程监测&#xff1a;系统可以实现对冷水表数据的远程监测&#xff0c;无…

趣话最大割问题:花果山之群猴博弈

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 编辑丨浪味仙 排版丨 沛贤 深度好文&#xff1a;3000字丨15分钟阅读 趋利避害&#xff0c;是所有生物遵循的自然法则&#xff0c;人类也不例外。 举个例子&#xff0c;假如你是某生鲜平台的配…

【Entity Framework】你要知道EF中功能序列与值转换

【Entity Framework】你要知道EF中功能序列与值转换 文章目录 【Entity Framework】你要知道EF中功能序列与值转换一、序列1.1 基本用法1.2 配置序列设置 二、值转换2.1 配置值转换器2.2 批量配置值转换器2.3 预定义的转换2.4 ValueConverter类2.5 内置转换器 三、应用3.1 简单…

Vue3基础笔记(3)高级绑定

一.Class绑定 数据绑定的一个常见需求场景师操纵元素的CSS class列表&#xff0c;因为class是attribute&#xff0c;我们可以和其他attribute一样使用v-bind将他们和动态的字符串绑定&#xff0c;但是在处理较为复杂的绑定时&#xff0c;拼接字符串容易出现错误。因此Vue专门为…

Python开源工具库使用之词云Wordcloud

文章目录 前言一、基本使用1.1 文本生成词云1.2 配置项 二、进阶用法2.1 自定义形状2.2 自定义着色2.3 自定义词频2.4 中文 三、实际案例3.1 工作报告词云3.2 周杰伦歌词词云 四、总结4.1 优点和局限性4.2 展望未来发展 参考 前言 当我们需要将大量文本数据可视化展示时&#…

为了执行SQL语句,MySQL的架构是怎样设计的

1. 把MySQL当个黑盒子一样执行SQL语句 上一讲我们已经说到&#xff0c;我们的系统采用数据库连接池的方式去并发访问数据库&#xff0c;然后数据库自己其实也会维护一个连 接池&#xff0c;其中管理了各种系统跟这台数据库服务器建立的所有连接 我们先看下图回顾一下 当我们的…

【PostmanJMeter】使用Postman和JMeter进行signature签名

一、前言 ​ 有些接口的请求会带上sign&#xff08;签名&#xff09;进行请求&#xff0c;各接口对sign的签名内容、方式可能不一样&#xff0c;但一般都是从接口的入参中选择部分内容组成一个字符串&#xff0c;然后再进行签名操作, 将结果赋值给sign; 完整规范的接口文档都会…

使用深度学习集成模型进行乳腺癌组织病理学图像分类

基于预训练的VGG16和VGG19架构训练了四种不同的模型&#xff08;即完全训练的 VGG16、微调的 VGG16、完全训练的 VGG19 和微调的 VGG19 模型&#xff09;。最初&#xff0c;我们对所有单独的模型进行了5倍交叉验证操作。然后&#xff0c;我们采用集成策略&#xff0c;取预测概率…

(一)C++自制植物大战僵尸集成开发环境安装

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/uzrnw 1、下载Visual Studio集成开发环境 首先在微软官网下载Visual Studio 2022 Community版本。Community版本是免费的&#xff0c;并且满足个人开发的各种需求。Visual Studio 2022 下载链接&#xff1a;微软官网。选…

maven引入外部jar包

将jar包放入文件夹lib包中 pom文件 <dependency><groupId>com.jyx</groupId><artifactId>Spring-xxl</artifactId><version>1.0-SNAPSHOT</version><scope>system</scope><systemPath>${project.basedir}/lib/Spr…

[lesson33]C++中的字符串类

C中的字符串类 历史遗留问题 C语言不支持真正意义上的字符串C语言用字符数组和一组函数实现字符串操作C语言不支持自定义类型&#xff0c;因此无法获得字符串类型 解决方案 从C到C的进化过程引入自定义类型在C中可以通过类完成字符串类型的定义 标准库中的字符串类 C语言直…

蓝桥杯——玩具蛇

题目 小蓝有—条玩具蛇&#xff0c;一共有16节&#xff0c;上面标着数字1至16。每—节都是一个正方形的形状。相邻的两节可以成直线或者成90度角。 小蓝还有一个44的方格盒子&#xff0c;用于存放玩具蛇&#xff0c;盒子的方格上依次标着字母A到Р共16个字母。 小蓝可以折叠自…

什么是分组分析法

调查数据显示&#xff0c;2019 年年末中国大陆总人口 140005 万人。从年龄构成看&#xff0c;16 至 59 周岁年末人数为 89640 万&#xff0c;占总人口的比重为 64.0%&#xff1b;60 周岁及以上人口 25388 万人&#xff0c;占总人口的 18.1%&#xff0c;其中 65 周岁及以上人口 …

力扣LeetCode138. 复制带随机指针的链表 两种解法(C语言实现)

目录 题目链接 题目分析 题目定位&#xff1a; 解题思路 解题思路1&#xff08;粗暴但是复杂度高&#xff09; 解题思路2&#xff08;巧妙并且复杂度低&#xff09; 题目链接 138. 复制带随机指针的链表https://leetcode-cn.com/problems/copy-list-with-random-pointer/ …

OpenCV基本图像处理操作(一)——图像基本操作与形态学操作

环境配置地址 图像显示 import cv2 #opencv读取的格式是BGR import numpy as np import matplotlib.pyplot as plt#Matplotlib是RGB imgcv2.imread(cat.jpg) img_gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) img_gray.shape cv2.imshow("img_gray", img_gray) cv2…

【详解算法流程+程序】DBSCAN基于密度的聚类算法+源码-用K-means和DBSCAN算法对银行数据进行聚类并完成用户画像数据分析课设源码资料包

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法。 与划分和层次聚类方法不同&#xff0c;它将簇定义为密度相连的点的最大集合&#xff0c;能够把具有足够高密度的区域划分为簇&#xff0c; 并可在噪声的空间数据…