Python----Python爬虫(多线程,多进程,协程爬虫)

注意:

        该代码爬取小说不久或许会失效,有时候该网站会被封禁,代码只供参考,不同小说不同网址会有差异 

神印王座II皓月当空最新章节_神印王座II皓月当空全文免费阅读-笔趣阁

一、多线程爬虫

1.1、单线程爬虫的问题

        爬虫通常被认为是IO密集型的程序,因为它们主要依赖于网络请求来获取数据。然而,IO处理的速度相对较慢,可能导致爬虫的整体速度受限。具体来说,单线程爬虫在处理大量网页时效率较低,主要存在以下几个问题:

  1. 速度慢:单线程爬虫只能一个接一个地请求网页,缺乏并发能力。在面对大量网页时,这种逐个请求的方式显著增加了爬取所需的时间。

  2. 资源利用率低:在等待网络响应的过程中,CPU处于闲置状态,未能充分利用系统资源。这种低效利用不仅影响了爬虫的速度,也使得系统资源浪费。

  3. 易受限于网络延迟:网络延迟是影响爬虫效率的重要因素。单线程爬虫在面对高延迟的网络时,整体爬取时间会显著延长,从而降低用户体验。

1.2、原理

        多线程爬虫的核心原理是利用多线程并行处理多个网页请求,从而提高网络请求的并发性,加速数据抓取的过程。在这种架构中,爬虫将URL队列中的链接分配给多个线程进行处理,每个线程负责发送网络请求并获取响应。

具体来说,爬虫的工作流程如下:

  1. URL队列:爬虫首先维护一个包含待爬取URL的队列。每个线程从这个队列中取出一个URL进行处理。

  2. 并行请求:多个线程同时运行,独立地发送网络请求。在等待响应的过程中,线程不会闲置,而是可以继续处理队列中的其他URL。这种并行处理显著减少了整体的爬取时间。

  3. 结果队列:每个线程在获取到网页响应后,将结果存储到一个结果队列中。这个结构确保了数据的有序存储,并允许其他线程安全地读取这些结果。

  4. 数据写入:另一些线程则负责从结果队列中读取数据,并将其写入文件或进行进一步处理。这种分工使得爬虫的各个部分能够高效协作,最大限度地提高资源利用率。

1.3、主要组成部分

1.3.1、URL队列和结果队列

  • URL队列:存储待爬取的URL链接,通常使用线程安全的队列(如queue.Queue),以便多个线程可以安全地访问和修改。

  • 结果队列:用于存放从网页中提取的结果,允许在爬取完成后统一处理或存储。

from queue import Queue
urls_queue = Queue()
out_queue = Queue()

1.3.2、类包装

使用多个线程,不停的取URL队列中的url,并进行处理:

import threading
class ThreadCrawl(threading.Thread):def __init__(self, queue, out_queue):threading.Thread.__init__(self)self.queue = queueself.out_queue = out_queuedef run(self):while True:item = self.queue.get()

如果队列为空,线程就会被阻塞,直到队列不为空。

处理队列中的 一条数据后,就需要通知队列已经处理完该条数据 

1.3.3、函数包装

from threading import Thread
def func(args):pass
if __name__ == '__main__':info_html = Queue()t1 = Thread(target=func,args=(info_html,))

1.3.4、线程池

import threading  # 导入 threading 模块,用于创建和管理线程  
import time       # 导入 time 模块,使用 sleep 来模拟工作  
import queue      # 导入 queue 模块,使用线程安全的队列  class Threadingpool():  def __init__(self, max_num=10):  # 初始化线程池,最大线程数量为 max_num  self.queue = queue.Queue(max_num)  # 创建一个最大大小为 max_num 的队列  for i in range(max_num):  # 将线程类的引用放入队列中  self.queue.put(threading.Thread)  def getthreading(self):  # 从队列中获取一个线程  return self.queue.get()  def addthreading(self):  # 将新的线程类引用放回队列  self.queue.put(threading.Thread)  def func(p, i):  # 每个线程执行的函数  time.sleep(1)  # 通过休眠1秒来模拟工作  print(i)       # 打印传递给函数的索引  p.addthreading()  # 线程完成后,将线程返回到池中  if __name__ == "__main__":  p = Threadingpool()  # 创建一个 Threadingpool 实例  for i in range(20):  thread = p.getthreading()  # 从池中获取一个线程  t = thread(target=func, args=(p, i))  # 创建一个新线程,目标函数和参数  t.start()  # 启动线程

1.4、多线程函数爬虫

import re  # 导入正则表达式模块  
import requests  # 导入请求库,用于发送HTTP请求  
from fake_useragent import UserAgent  # 导入假用户代理库,用于伪装请求的用户代理  
from lxml import etree  # 导入lxml库,用于解析HTML  
from threading import Thread  # 导入线程模块,用于实现多线程  
import time  # 导入时间模块,用于控制延时  def sanitize_filename(title):  # 替换 Windows 文件名中的无效字符  return re.sub(r'[<>:"/\\|?*]', '', title)  def get_new_url(url):  # 设置请求头,伪装成浏览器  header = {'User-Agent': UserAgent().edge}  # 发送GET请求获取网页内容  resp = requests.get(url, header)  resp.encoding = 'gbk'  # 设置网页编码为'gbk'  e = etree.HTML(resp.text)  # 解析网页内容为HTML树结构  titles = []  # 存储章节标题  new_urls = []  # 存储章节链接  # 遍历指定范围内的章节  for i in range(13, 516):  if i == 368:  # 跳过特定章节  continue  # 获取章节标题并打印  print(e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/text()")[0])  titles.append(e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/text()")[0])  # 添加标题到列表  # 构造章节链接并添加到列表  new_urls.append('https://www.bbiquge.cc/book_61985/' + e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/@href")[0])  return titles, new_urls  # 返回标题和链接列表  def spider(title, new_url):  # 设置请求头,伪装成浏览器  header = {'User-Agent': UserAgent().edge}  # 发送GET请求获取章节内容  resp = requests.get(new_url, header)  resp.encoding = 'gbk'  # 设置编码为'gbk'  e = etree.HTML(resp.text)  # 解析网页内容为HTML树结构  safe_title = sanitize_filename(title)  # 清理标题以作为文件名  print(title)  # 打印当前正在抓取的章节标题  content = e.xpath("//div[@id='content']/text()")  # 获取章节内容  # 打开文件以写入章节内容  with open(f'./神印王座/{safe_title}.txt', 'a+', encoding='utf-8') as f:  for i in content:  f.write(i.strip() + "\n")  # 写入内容并清理空白  time.sleep(2)  # 每次抓取后暂停2秒,防止过于频繁的请求  if __name__ == '__main__':  url = 'https://www.bbiquge.cc/book_61985/'  # 目标网址  titles, new_urls = get_new_url(url)  # 获取章节标题和链接  threads = []  # 存储线程列表  # 为每个章节创建一个线程进行抓取  for title, new_url in zip(titles, new_urls):  thread = Thread(target=spider, args=(title, new_url))  # 创建线程  threads.append(thread)  # 添加线程到列表  thread.start()  # 启动线程  # 等待所有线程完成  for thread in threads:  thread.join()  # 等待每个线程结束

1.5、多线程类爬虫

import re  # 导入正则表达式模块  
import requests  # 导入请求库,用于发送HTTP请求  
from fake_useragent import UserAgent  # 导入假用户代理库,用于伪装请求的用户代理  
from lxml import etree  # 导入lxml库,用于解析HTML  
from threading import Thread  # 导入线程模块  
import time  # 导入时间模块,用于控制延时  class NovelSpider(Thread):  def __init__(self, title, new_url):  super().__init__()  # 调用父类的构造函数  self.title = title  # 章节标题  self.new_url = new_url  # 章节链接  self.headers = {'User-Agent': UserAgent().edge}  # 请求头  @staticmethod  def sanitize_filename(title):  # 替换 Windows 文件名中的无效字符  return re.sub(r'[<>:"/\\|?*]', '', title)  def run(self):  # 发送GET请求获取章节内容  resp = requests.get(self.new_url, headers=self.headers)  resp.encoding = 'gbk'  # 设置编码为'gbk'  e = etree.HTML(resp.text)  # 解析网页内容为HTML树结构  safe_title = self.sanitize_filename(self.title)  # 清理标题以作为文件名  print(f"抓取中: {safe_title}")  # 打印当前正在抓取的章节标题  content = e.xpath("//div[@id='content']/text()")  # 获取章节内容  # 打开文件以写入章节内容  with open(f'./神印王座/{safe_title}.txt', 'a+', encoding='utf-8') as f:  for i in content:  f.write(i.strip() + "\n")  # 写入内容并清理空白  time.sleep(2)  # 每次抓取后暂停2秒,防止过于频繁的请求  class NovelCrawler:  def __init__(self, base_url):  self.base_url = base_url  # 基础网址  self.headers = {'User-Agent': UserAgent().edge}  # 请求头  self.titles = []  # 存储章节标题  self.new_urls = []  # 存储章节链接  def get_new_url(self):  # 发送GET请求获取网页内容  resp = requests.get(self.base_url, headers=self.headers)  resp.encoding = 'gbk'  # 设置网页编码为'gbk'  e = etree.HTML(resp.text)  # 解析网页内容为HTML树结构  # 遍历指定范围内的章节  for i in range(13, 516):  if i == 368:  # 跳过特定章节  continue  title = e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/text()")[0]  # 获取章节标题  print(title)  # 打印章节标题  self.titles.append(title)  # 添加标题到列表  new_url = 'https://www.bbiquge.cc/book_61985/' + e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/@href")[0]  # 构造章节链接  self.new_urls.append(new_url)  # 添加链接到列表  def run(self):  self.get_new_url()  # 获取章节标题和链接  threads = []  # 存储线程列表  # 为每个章节创建一个线程进行抓取  for title, new_url in zip(self.titles, self.new_urls):  spider = NovelSpider(title, new_url)  # 创建爬虫实例  threads.append(spider)  # 添加线程到列表  spider.start()  # 启动线程  # 等待所有线程完成  for thread in threads:  thread.join()  # 等待每个线程结束  if __name__ == '__main__':  url = 'https://www.bbiquge.cc/book_61985/'  # 目标网址  crawler = NovelCrawler(url)  # 创建爬虫控制器实例  crawler.run()  # 运行爬虫

1.6、 多线程--线程池

import re  # 导入正则表达式模块  
import requests  # 导入请求库,用于发送HTTP请求  
from fake_useragent import UserAgent  # 导入假用户代理库,用于伪装请求的用户代理  
from lxml import etree  # 导入lxml库,用于解析HTML  
from concurrent.futures import ThreadPoolExecutor  # 导入线程池执行器  
import time  # 导入时间模块,用于控制延时  def sanitize_filename(title):  # 替换 Windows 文件名中的无效字符  return re.sub(r'[<>:"/\\|?*]', '', title)  def get_new_url(url):  # 设置请求头,伪装成浏览器  header = {'User-Agent': UserAgent().edge}  # 发送GET请求获取网页内容  resp = requests.get(url, headers=header)  resp.encoding = 'gbk'  # 设置网页编码为'gbk'  e = etree.HTML(resp.text)  # 解析网页内容为HTML树结构  titles = []  # 存储章节标题  new_urls = []  # 存储章节链接  # 遍历指定范围内的章节  for i in range(13, 516):  if i == 368:  # 跳过特定章节  continue  # 获取章节标题并打印  title = e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/text()")[0]  print(title)  # 打印章节标题  titles.append(title)  # 添加标题到列表  # 构造章节链接并添加到列表  new_urls.append('https://www.bbiquge.cc/book_61985/' + e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/@href")[0])  return titles, new_urls  # 返回标题和链接列表  def spider(title, new_url):  # 设置请求头,伪装成浏览器  header = {'User-Agent': UserAgent().edge}  # 发送GET请求获取章节内容  resp = requests.get(new_url, headers=header)  resp.encoding = 'gbk'  # 设置编码为'gbk'  e = etree.HTML(resp.text)  # 解析网页内容为HTML树结构  safe_title = sanitize_filename(title)  # 清理标题以作为文件名  print(f"抓取中: {safe_title}")  # 打印当前正在抓取的章节标题  content = e.xpath("//div[@id='content']/text()")  # 获取章节内容  # 打开文件以写入章节内容  with open(f'./神印王座/{safe_title}.txt', 'a+', encoding='utf-8') as f:  for i in content:  f.write(i.strip() + "\n")  # 写入内容并清理空白  time.sleep(2)  # 每次抓取后暂停2秒,防止过于频繁的请求  if __name__ == '__main__':  url = 'https://www.bbiquge.cc/book_61985/'  # 目标网址  titles, new_urls = get_new_url(url)  # 获取章节标题和链接  # 使用线程池进行抓取  with ThreadPoolExecutor(max_workers=10) as executor:  # 设置最大工作线程数  # 为每个章节提交任务  for title, new_url in zip(titles, new_urls):  executor.submit(spider, title, new_url)  # 提交任务到线程池

二、多进程爬虫

        multiprocessing是python的多进程管理包,和threading.Thread 类似 multiprocessing模块

        multiprocessing模块可以让程序员在给定的机器上充分的利用CPU 在multiprocessing中,通过创建Process对象生成进程,然后调用 它的start()方法

2.1、多进程函数爬虫

import re  # 导入正则表达式模块  
import requests  # 导入请求库,用于发送HTTP请求  
from fake_useragent import UserAgent  # 导入假用户代理库,用于伪装请求的用户代理  
from lxml import etree  # 导入lxml库,用于解析HTML  
from multiprocessing import Process, Manager  # 导入进程和管理器模块  
import time  # 导入时间模块,用于控制延时  def sanitize_filename(title):  # 替换 Windows 文件名中的无效字符  return re.sub(r'[<>:"/\\|?*]', '', title)  def get_new_url(url):  # 设置请求头,伪装成浏览器  header = {'User-Agent': UserAgent().edge}  # 发送GET请求获取网页内容  resp = requests.get(url, headers=header)  resp.encoding = 'gbk'  # 设置网页编码为'gbk'  e = etree.HTML(resp.text)  # 解析网页内容为HTML树结构  titles = []  # 存储章节标题  new_urls = []  # 存储章节链接  # 遍历指定范围内的章节  for i in range(13, 516):  if i == 368:  # 跳过特定章节  continue  # 获取章节标题并打印  title = e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/text()")[0]  print(title)  # 打印章节标题  titles.append(title)  # 添加标题到列表  # 构造章节链接并添加到列表  new_urls.append('https://www.bbiquge.cc/book_61985/' + e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/@href")[0])  return titles, new_urls  # 返回标题和链接列表  def spider(title, new_url):  # 设置请求头,伪装成浏览器  header = {'User-Agent': UserAgent().edge}  # 发送GET请求获取章节内容  resp = requests.get(new_url, headers=header)  resp.encoding = 'gbk'  # 设置编码为'gbk'  e = etree.HTML(resp.text)  # 解析网页内容为HTML树结构  safe_title = sanitize_filename(title)  # 清理标题以作为文件名  print(f"抓取中: {safe_title}")  # 打印当前正在抓取的章节标题  content = e.xpath("//div[@id='content']/text()")  # 获取章节内容  # 打开文件以写入章节内容  with open(f'./神印王座/{safe_title}.txt', 'a+', encoding='utf-8') as f:  for i in content:  f.write(i.strip() + "\n")  # 写入内容并清理空白  time.sleep(2)  # 每次抓取后暂停2秒,防止过于频繁的请求  if __name__ == '__main__':  url = 'https://www.bbiquge.cc/book_61985/'  # 目标网址  titles, new_urls = get_new_url(url)  # 获取章节标题和链接  processes = []  # 存储进程列表  # 为每个章节创建一个进程进行抓取  for title, new_url in zip(titles, new_urls):  process = Process(target=spider, args=(title, new_url))  # 创建进程  processes.append(process)  # 添加进程到列表  process.start()  # 启动进程  # 等待所有进程完成  for process in processes:  process.join()  # 等待每个进程结束

2.2、多进程类爬虫

import re  # 导入正则表达式模块  
import requests  # 导入请求库,用于发送HTTP请求  
from fake_useragent import UserAgent  # 导入假用户代理库,用于伪装请求的用户代理  
from lxml import etree  # 导入lxml库,用于解析HTML  
from multiprocessing import Process  # 导入进程模块  
import time  # 导入时间模块,用于控制延时  class NovelSpider(Process):  # 继承自 Process  def __init__(self, title, new_url):  super().__init__()  # 调用父类的构造函数  self.title = title  # 章节标题  self.new_url = new_url  # 章节链接  self.headers = {'User-Agent': UserAgent().edge}  # 请求头  @staticmethod  def sanitize_filename(title):  # 替换 Windows 文件名中的无效字符  return re.sub(r'[<>:"/\\|?*]', '', title)  def run(self):  # 发送GET请求获取章节内容  resp = requests.get(self.new_url, headers=self.headers)  resp.encoding = 'gbk'  # 设置编码为'gbk'  e = etree.HTML(resp.text)  # 解析网页内容为HTML树结构  safe_title = self.sanitize_filename(self.title)  # 清理标题以作为文件名  print(f"抓取中: {safe_title}")  # 打印当前正在抓取的章节标题  content = e.xpath("//div[@id='content']/text()")  # 获取章节内容  # 打开文件以写入章节内容  with open(f'./神印王座/{safe_title}.txt', 'a+', encoding='utf-8') as f:  for i in content:  f.write(i.strip() + "\n")  # 写入内容并清理空白  time.sleep(2)  # 每次抓取后暂停2秒,防止过于频繁的请求  class NovelCrawler:  def __init__(self, base_url):  self.base_url = base_url  # 基础网址  self.headers = {'User-Agent': UserAgent().edge}  # 请求头  self.titles = []  # 存储章节标题  self.new_urls = []  # 存储章节链接  def get_new_url(self):  # 发送GET请求获取网页内容  resp = requests.get(self.base_url, headers=self.headers)  resp.encoding = 'gbk'  # 设置网页编码为'gbk'  e = etree.HTML(resp.text)  # 解析网页内容为HTML树结构  # 遍历指定范围内的章节  for i in range(13, 516):  if i == 368:  # 跳过特定章节  continue  title = e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/text()")[0]  # 获取章节标题  print(title)  # 打印章节标题  self.titles.append(title)  # 添加标题到列表  new_url = 'https://www.bbiquge.cc/book_61985/' + e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/@href")[0]  # 构造章节链接  self.new_urls.append(new_url)  # 添加链接到列表  def run(self):  self.get_new_url()  # 获取章节标题和链接  processes = []  # 存储进程列表  # 为每个章节创建一个进程进行抓取  for title, new_url in zip(self.titles, self.new_urls):  spider = NovelSpider(title, new_url)  # 创建爬虫实例  processes.append(spider)  # 添加进程到列表  spider.start()  # 启动进程  # 等待所有进程完成  for process in processes:  process.join()  # 等待每个进程结束  if __name__ == '__main__':  url = 'https://www.bbiquge.cc/book_61985/'  # 目标网址  crawler = NovelCrawler(url)  # 创建爬虫控制器实例  crawler.run()  # 运行爬虫

三、协程爬虫

        网络爬虫速度效率慢,多部分在于阻塞IO这块(网络/磁盘)。在阻塞 时,CPU的中内核是可以处理别的非IO操作。因此可以考虑使用协 程来提升爬虫效率,这种操作的技术就是协程

协程一种轻量级线程,拥有自己的寄存器上下文和栈,本质是一个进程

相对于多进程,无需线程上下文切换的开销,无需原子操作锁定及同步的开销

简单的说就是让阻塞的子程序让出CPU给可以执行的子程序


一个进程包含多个线程,一个线程可以包含多个协程

多个线程相对独立,线程的切换受系统控制。 多个协程也相对独立,但是其切换由程序自己控制

pip install aiohttp 

属性或方法功能
aiohttp.ClientSession()获取客户端函数
session.get(url)发送get请求
seesion.post(url)发送post请求
resp.status获取响应状态码
resp.url获取响应url地址
resp.cookies获取响应cookie内容
resp.headers获取响应头信息
resp.read()获取响应bytes类型
resp.text()获取响应文本内容
import re  # 导入正则表达式模块  
import aiohttp  # 导入异步HTTP请求库  
import asyncio  # 导入异步库  
from fake_useragent import UserAgent  # 导入假用户代理库,用于伪装请求的用户代理  
from lxml import etree  # 导入lxml库,用于解析HTML  async def sanitize_filename(title):  # 替换 Windows 文件名中的无效字符  return re.sub(r'[<>:"/\\|?*]', '', title)  async def fetch(session, url):  # 异步获取网页内容  async with session.get(url) as response:  return await response.text()  async def get_new_url(url):  header = {'User-Agent': UserAgent().edge}  async with aiohttp.ClientSession() as session:  # 创建异步会话  resp_text = await fetch(session, url)  # 获取网页内容  resp_text.encoding = 'gbk'  # 设置网页编码为'gbk'  e = etree.HTML(resp_text)  # 解析网页内容为HTML树结构  titles = []  # 存储章节标题  new_urls = []  # 存储章节链接  # 遍历指定范围内的章节  for i in range(13, 516):  if i == 368:  # 跳过特定章节  continue  title = e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/text()")[0]  # 获取章节标题  print(title)  # 打印章节标题  titles.append(title)  # 添加标题到列表  # 构造章节链接并添加到列表  new_urls.append('https://www.bbiquge.cc/book_61985/' + e.xpath(f"//div[@id='list']/dl/dd[{i}]/a/@href")[0])  return titles, new_urls  # 返回标题和链接列表  async def spider(title, new_url):  header = {'User-Agent': UserAgent().edge}  async with aiohttp.ClientSession() as session:  # 创建异步会话  resp_text = await fetch(session, new_url)  # 异步获取章节内容  resp_text.encoding = 'gbk'  # 设置编码为'gbk'  e = etree.HTML(resp_text)  # 解析网页内容为HTML树结构  safe_title = await sanitize_filename(title)  # 清理标题以作为文件名  print(f"抓取中: {safe_title}")  # 打印当前正在抓取的章节标题  content = e.xpath("//div[@id='content']/text()")  # 获取章节内容  # 打开文件以写入章节内容  with open(f'./神印王座/{safe_title}.txt', 'a+', encoding='utf-8') as f:  for line in content:  f.write(line.strip() + "\n")  # 写入内容并清理空白  async def main():  url = 'https://www.bbiquge.cc/book_61985/'  # 目标网址  titles, new_urls = await get_new_url(url)  # 获取章节标题和链接  # 创建任务列表并并发执行  tasks = [spider(title, new_url) for title, new_url in zip(titles, new_urls)]  await asyncio.gather(*tasks)  # 使用 gather() 并发  if __name__ == '__main__':  asyncio.run(main())  # 运行主协程函数

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux(ftrace)__mcount的实现原理

Linux 内核调试工具ftrace 之&#xff08;_mcount的实现原理&#xff09; ftrace 是 Linux 内核中的一种跟踪工具&#xff0c;主要用于性能分析、调试和内核代码的执行跟踪。它通过在内核代码的关键点插入探针&#xff08;probe&#xff09;来记录函数调用和执行信息。这对于开…

网络层IP协议

基本概念 主机&#xff1a;有IP地址&#xff0c;但是不进行路由控制的设备。 路由器&#xff1a;有IP地址&#xff0c;又能进行路由控制。 节点&#xff1a;主机和路由器的统称。 协议头格式 4位版本号&#xff1a;指定IP协议的版本。对于IPv4来说&#xff0c;就是4 4位首…

计算机毕业设计SpringBoot+Vue.js在线课程管理系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

【腾讯云】AI驱动TDSQL-C Serveress 数据库技术实战营-如何是从0到1体验电商可视化分析小助手得统计功能,一句话就能输出目标统计图

欢迎来到《小5讲堂》 这是《腾讯云》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 背景效果图流程图创建数据库 基本信息数据库配置设置密码控制台开…

Java里的ArrayList和LinkedList有什么区别?

大家好&#xff0c;我是锋哥。今天分享关于【Java里的ArrayList和LinkedList有什么区别&#xff1f;】面试题。希望对大家有帮助&#xff1b; Java里的ArrayList和LinkedList有什么区别&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 ArrayList 和 Lin…

盛京开源社区加入 GitCode,书写东北开源生态新篇章

在数字化转型与开源技术蓬勃发展的浪潮下&#xff0c;开源社区已成为推动技术创新的核心力量。盛京开源社区&#xff08;SJOSC&#xff09;作为沈阳地区的开源交流平台&#xff0c;始终致力于连接开发者、企业及高校&#xff0c;构建区域技术生态圈。 现在&#xff0c;盛京开源…

SQL Server 创建用户并授权

创建用户前需要有一个数据库&#xff0c;创建数据库命令如下&#xff1a; CREATE DATABASE [数据库名称]; CREATE DATABASE database1;一、创建登录用户 方式1&#xff1a;SQL命令 命令格式&#xff1a;CREATE LOGIN [用户名] WITH PASSWORD ‘密码’; 例如&#xff0c;创…

vue3:三项目增加404页面

一、路由添加 1、官网地址 带参数的动态路由匹配 | Vue Routerhttps://router.vuejs.org/zh/guide/essentials/dynamic-matching.html 2、复制核心语句 { path: /:pathMatch(.*)*, name: NotFound, component: NotFound } 3、粘贴到路由index.js中 4、建立页面 在view文件夹…

GitCode 助力 JeeSite:开启企业级快速开发新篇章

项目仓库&#xff08;点击阅读原文链接可直达前端仓库&#xff09; https://gitcode.com/thinkgem/jeesite 企业级快速开发的得力助手&#xff1a;JeeSite 快速开发平台 JeeSite 不仅仅是一个普通的后台开发框架&#xff0c;而是一套全面的企业级快速开发解决方案。后端基于 …

矽电股份业绩下滑:毛利率也欠佳,应收账款攀升回款比率放缓

《港湾商业观察》施子夫 近期&#xff0c;矽电半导体设备&#xff08;深圳&#xff09;股份有限公司&#xff08;以下简称&#xff0c;矽电股份&#xff09;的深交所IPO注册获得生效。 公开信息显示&#xff0c;2022年6月&#xff0c;矽电股份的创业板IPO获受理&#xff0c;保…

MySQL实现文档全文搜索,分词匹配多段落重排展示,知识库搜索原理分享

一、背景 在文档搜索场景中&#xff0c;高效精准的搜索功能至关重要&#xff0c;能提升检索效率&#xff0c;为用户提供精准、快速的信息获取体验&#xff0c;提高工作效率。在文档管理系统里&#xff0c;全文搜索是非常重要的功能之一。随着文档数量增长&#xff0c;如何快速…

十、大数据资源平台功能架构

一、大数据资源平台的功能架构图总体结构 大数据资源平台功能架构图 关键组件&#xff1a; 1.用户&#xff08;顶行&#xff09; 此部分标识与平台交互的各种利益相关者。 其中包括&#xff1a; 市领导 各部门分析师 区政府 外部组织 公民 开发人员 运营经理 2.功能模…

现代前端框架渲染机制深度解析:虚拟DOM到编译时优化

引言&#xff1a;前端框架的性能进化论 TikTok Web将React 18迁移至Vue 3后&#xff0c;点击响应延迟降低42%&#xff0c;内存占用减少35%。Shopify采用Svelte重构核心交互模块&#xff0c;首帧渲染速度提升580%。Discord在Next.js 14中启用React Server Components后&#xf…

【子网掩码计算器:Python + Tkinter 实现】

子网掩码计算器&#xff1a;Python Tkinter 实现 引言代码功能概述代码实现思路1. 界面设计2. 功能实现3. 事件处理 子网掩码计算器实现步骤1. 导入必要的库2. 定义主窗口类 SubnetCalculatorApp3. 创建菜单栏4. 创建界面组件5. 判断 IP 地址类别6. 计算子网信息7. 其他功能函…

视频推拉流EasyDSS点播平台云端录像播放异常问题的排查与解决

EasyDSS视频直播点播平台是一个功能全面的系统&#xff0c;提供视频转码、点播、直播、视频推拉流以及H.265视频播放等一站式服务。该平台与RTMP高清摄像头配合使用&#xff0c;能够接收无人机设备的实时视频流&#xff0c;实现无人机视频推流直播和巡检等多种应用。 最近&…

android 文本控件显示滑动条并自动滑动到最底部

文本框滑动需要增加控件 设置属性显示滑动条垂直滑动 显示滑动条 自动滚动到最后一行&#xff1a; private ScrollView mscrollView; mOutput.setMovementMethod(ScrollingMovementMethod.getInstance()); mscrollView (ScrollView) findViewById(R.id.scrollview); mscrol…

#渗透测试#批量漏洞挖掘#某图创图书馆集群管理系统updOpuserPw SQL注入(CVE-2021-44321)

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

1.C语言初识

C语言初识 C语言初识基础知识hello world数据类型变量、常量变量命名变量分类变量的使用变量的作用域 常量字符字符串转义字符 选择语句循环语句 函数&#xff1b;数组函数数组数组下标 操作符操作符算术操作符移位操作符、位操作符赋值操作符单目操作符关系操作符逻辑操作符条…

Redis通用命令

目录 Redis客户端 ​编辑Redis核心命令 Redis通用命令 keys exists del expire ttl type 总结 Redis客户端 Redis也是一个基于客户端-服务器结构的程序&#xff0c;为什么说也呢&#xff1f;因为MySQL也是一个基于客户端服务器的结构。 Redis客户端可以和服务器在…

第49天:Web开发-JavaEE应用SpringBoot栈模版注入ThymeleafFreemarkerVelocity

#知识点 1、安全开发-JavaEE-开发框架-SpringBoot&路由&传参 2、安全开发-JavaEE-模版引擎-Thymeleaf&Freemarker&Velocity 一、开发框架-SpringBoot 参考&#xff1a;https://springdoc.cn/spring-boot/ 访问SpringBoot创建的网站 1、路由映射 RequestMapping…