2024-08-13



import scrapy
 
class DoubanMovieItem(scrapy.Item):
    # 定义爬取的字段
    movie_name = scrapy.Field()
    movie_rating = scrapy.Field()
    movie_comment = scrapy.Field()
 
class DoubanMovieSpider(scrapy.Spider):
    name = 'douban_movie'
    allowed_domains = ['douban.com']
    start_urls = ['https://movie.douban.com/top250']
 
    def parse(self, response):
        # 提取电影信息的xpath路径
        movie_selectors = response.xpath('//div[@class="info"]')
        for movie_selector in movie_selectors:
            item = DoubanMovieItem()
            # 提取电影名称
            movie_name = movie_selector.xpath('.//a/span[1]/text()').extract_first()
            item['movie_name'] = movie_name.strip() if movie_name else None
            # 提取电影评分
            movie_rating = movie_selector.xpath('.//div[@class="star"]/span[2]/text()').extract_first()
            item['movie_rating'] = movie_rating.strip() if movie_rating else None
            # 提取电影评论
            movie_comment = movie_selector.xpath('.//p[@class="quote"]/span/text()').extract_first()
            item['movie_comment'] = movie_comment.strip() if movie_comment else None
            yield item
 
        # 提取下一页链接并进行爬取
        next_page_url = response.xpath('//span[@class="next"]/a/@href').extract_first
        if next_page_url:
            next_page_full_url = response.urljoin(next_page_url)
            yield scrapy.Request(next_page_full_url, callback=self.parse)

这段代码实现了一个简单的Scrapy爬虫,用于抓取豆瓣电影TOP250的电影名称、评分和评论。它使用XPath选择器来定位页面元素,并使用Item对象来存储爬取的数据。此外,它还实现了简单的分页逻辑来爬取所有页的数据。

2024-08-13



import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from statsmodels.tsa.arima_model import ARIMA
from fbprophet import Prophet
 
# 假设我们有以下函数来获取智慧交通数据
def get_data(city, date):
    # 这里应该是获取数据的代码,但由于数据不公开,我们模拟一些数据返回
    return pd.DataFrame({
        'time': pd.date_range(start=date, periods=24*7, freq='H'),
        'car_count': np.random.randint(1000, 10000, size=24*7)
    })
 
# 获取数据
city = '北京'
date = '2021-01-01'
data = get_data(city, date)
 
# 数据预处理
data['hour'] = data['time'].dt.hour
data = data.set_index('time')
 
# 使用fbprophet进行时间序列预测
model = Prophet(daily_seasonality=True, weekly_seasonality=True)
model.fit(data)
future = model.make_future_dataframe(periods=24*7)
forecast = model.predict(future)
 
# 画出预测图
fig1 = model.plot(forecast)
 
# 保存图表
fig1.savefig(f'prophet_prediction_{city}.png')
 
# 输出预测结果
print(forecast[['ds', 'yhat']])

这个示例展示了如何使用Prophet模型进行时间序列预测,并将预测结果保存为图片文件。注意,这里的数据是模拟的,实际应用中需要替换为实际的交通数据。

2024-08-13



import requests
from bs4 import BeautifulSoup
import pandas as pd
 
# 设置请求头,模拟浏览器访问
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.3'}
 
def get_data(url):
    response = requests.get(url, headers=headers)
    soup = BeautifulSoup(response.text, 'lxml')
    data = soup.find_all('div', class_='title')
    rank = [i.span.get_text() for i in soup.find_all('div', class_='num')]
    names = [i.a.get_text() for i in data]
    hrefs = ['https://www.toutiao.com' + i.a.get('href') for i in data]
    return rank, names, hrefs
 
def main(url):
    rank, names, hrefs = get_data(url)
    data = pd.DataFrame(list(zip(rank, names, hrefs)), columns=['排名', '名称', '链接'])
    print(data)
    data.to_csv('今日头条热榜.csv', index=False, encoding='utf-8')
 
if __name__ == '__main__':
    url = 'https://www.toutiao.com/hotwords/'
    main(url)

这段代码首先定义了请求头,用于模拟浏览器访问网页。get_data 函数用于获取网页数据,并通过BeautifulSoup进行解析。main 函数则是程序的主要逻辑,它调用get_data函数获取数据,并将数据存储在一个DataFrame中,最后将数据保存到CSV文件中。最后,在__name____main__时,执行主函数,开始爬取数据。

2024-08-13

要使用Python构建一个企业级的高可用海量爬虫调度系统,可以选择使用Kubernetes和Python的第三方库如Celery来实现分布式任务调度,以及Scrapy来实现爬虫。

以下是一个基本的架构示例:

  1. Kubernetes:负责整个系统的部署、扩缩容和服务发现。
  2. Celery:负责分布式任务调度。
  3. Scrapy:用于实现爬虫。

以下是一个简单的Celery配置示例:




# celery_tasks.py
from celery import Celery
 
app = Celery('my_crawler', broker='redis://localhost:6379/0', backend='redis://localhost:6379/0')
 
@app.task
def add(x, y):
    return x + y

在Kubernetes中部署Celery:




# celery-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: celery-worker
spec:
  replicas: 3
  selector:
    matchLabels:
      component: celery-worker
  template:
    metadata:
      labels:
        component: celery-worker
    spec:
      containers:
      - name: celery-worker
        image: my_celery_worker_image
        command: celery worker -A my_crawler -l info

在Scrapy中创建爬虫项目,并配置为在Celery中运行:




# myspider.py
import scrapy
from celery_tasks.tasks import add
 
class MySpider(scrapy.Spider):
    name = 'myspider'
 
    def parse(self, response):
        # 假设爬取到的数据为item
        item = ...
        # 将爬取的数据提交给Celery进行异步处理
        add.delay(item)

这个例子展示了如何使用Celery和Scrapy来构建一个简单的分布式爬虫系统。在实际部署中,你需要考虑更多的细节,如错误处理、日志记录、监控、安全性等。此外,你还需要搭配Kubernetes的服务发现和自动扩缩容功能来保证系统的高可用性和扩展性。

2024-08-13

要使用Python爬取豆瓣电影评论,你可以使用requests库获取网页内容,然后用BeautifulSoup解析网页。以下是一个简单的示例代码:




import requests
from bs4 import BeautifulSoup
import time
 
# 设置HTTP请求头部,模拟浏览器访问
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.3'}
 
def get_comments(url):
    # 获取网页内容
    response = requests.get(url, headers=headers)
    response.raise_for_status()  # 检查请求是否成功
    soup = BeautifulSoup(response.text, 'lxml')  # 解析网页
 
    # 提取评论内容
    comments = soup.find_all('div', class_='comment')
    for comment in comments:
        content = comment.find('div', class_='comment-content').text.strip()
        author = comment.find('span', class_='comment-info').text.strip()
        print(f'评论内容:{content}\n作者:{author}\n')
 
# 主函数
def main(url):
    # 循环抓取多页评论
    for page in range(1, 11):  # 假设只抓取前10页
        print(f'正在抓取第{page}页评论...')
        page_url = f'{url}&page={page}'
        get_comments(page_url)
        time.sleep(2)  # 暂停2秒,减少对服务器的请求频率
 
if __name__ == '__main__':
    movie_url = 'https://movie.douban.com/subject/1292720/comments?sort=new_score'
    main(movie_url)

请注意,由于豆瓣网站可能有反爬机制,实际运行时可能需要处理登录验证、反爬机制等问题。此外,频繁的爬取数据可能会对豆瓣服务器造成压力,应遵守豆瓣的爬虫政策。

2024-08-13



# 导入必要的库
import pandas as pd
 
# 创建示例DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [5, 4, 3, 2, 1],
    'C': [10, 20, 30, 40, 50]
})
 
# 1. 查看DataFrame的前几行和后几行数据
print(df.head())  # 默认显示前5行
print(df.tail(3))  # 显示后3行
 
# 2. 查看DataFrame的统计信息
print(df.describe())
 
# 3. 对DataFrame进行排序
sorted_df = df.sort_values(by='A')
print(sorted_df)
 
# 4. 选择特定列
print(df[['A', 'B']])
 
# 5. 使用条件过滤数据
filtered_df = df[df['A'] > 2]
print(filtered_df)
 
# 6. 分组聚合
grouped_df = df.groupby('A').sum()
print(grouped_df)
 
# 7. 合并DataFrame
df1 = df.copy()
df1['D'] = [100, 200, 300, 400, 500]
merged_df = pd.merge(df, df1, on='A')
print(merged_df)
 
# 8. 重塑和填充DataFrame
reshape_df = df.stack()
padded_df = df.pad()
print(reshape_df)
print(padded_df)
 
# 9. 将DataFrame导出到CSV文件
df.to_csv('data.csv', index=False)
 
# 10. 将CSV文件导入到DataFrame
loaded_df = pd.read_csv('data.csv')
print(loaded_df)

这段代码展示了如何使用Pandas库中的常用函数来处理DataFrame数据。从查看数据、统计信息、排序和过滤,到分组聚合、合并和重塑以及导入导出操作,涵盖了数据处理的常用步骤。

2024-08-13

在Spring Boot中实现本地文件/图片上传并生成URL地址,你可以使用MultipartFile接口来处理上传的文件,并使用Spring的ResourceLoader来获取文件的URL。以下是一个简单的例子:

  1. 添加依赖到pom.xml



<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 创建一个控制器来处理文件上传:



import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
 
@RestController
public class FileUploadController {
 
    @Value("${upload.path}")
    private String uploadPath;
 
    private final ResourceLoader resourceLoader;
 
    public FileUploadController(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
 
    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            return "文件为空";
        }
 
        // 确定文件存储路径
        String filename = file.getOriginalFilename();
        File destFile = new File(Paths.get(uploadPath, filename).toString());
 
        // 保存文件
        file.transferTo(destFile);
 
        // 生成URL
        String fileUrl = resourceLoader.getResource("file:" + uploadPath).getURI().toString();
        return "文件上传成功,URL: " + fileUrl + filename;
    }
}
  1. application.properties中配置上传路径:



upload.path=/path/to/your/upload/directory
  1. 运行Spring Boot应用,并使用POST请求上传文件。

确保上传的目录对Spring Boot应用有写权限,并且正确配置了服务器的静态资源映射,以便能够通过生成的URL访问文件。

2024-08-13

在Python中,取余、取整、四舍五入、向上取整和向下取整可以使用内置的函数或运算符。

取余:使用 % 运算符




remainder = number % divisor

取整:

  • 向下取整:使用 math.floor() 函数



import math
floor = math.floor(number)
  • 向上取整:使用 math.ceil() 函数



import math
ceil = math.ceil(number)

四舍五入:使用 round() 函数




rounded = round(number)

向上取整和向下取整也可以使用内置的 int() 函数,但它会根据传入的浮点数返回它的整数部分(向零取整)。

例子:




number = 3.6
 
# 取余
remainder = number % 2  # 结果是 1
 
# 向下取整
import math
floor = math.floor(number)  # 结果是 3
 
# 向上取整
import math
ceil = math.ceil(number)  # 结果是 4
 
# 四舍五入
rounded = round(number)  # 结果是 4
 
# 向零取整
int_val = int(number)  # 结果是 3
2024-08-13

解释:

ModuleNotFoundError: No module named 'numpy.core._multiarray_um' 错误表明 Python 无法找到名为 numpy.core._multiarray_um 的模块。这通常是因为 NumPy 没有正确安装,或者安装的 NumPy 版本有问题。

解决方法:

  1. 确认 NumPy 是否已安装:在命令行中运行 pip show numpy 查看 NumPy 是否已安装以及其版本信息。
  2. 如果未安装,使用 pip install numpy 安装 NumPy。
  3. 如果已安装,但问题仍然存在,可以尝试更新 NumPy 到最新版本:pip install --upgrade numpy
  4. 确保你的 Python 环境(如虚拟环境)中安装了 NumPy,如果你使用的是虚拟环境,确保你已激活该环境。
  5. 如果问题依旧,可能是 Python 环境的问题,检查你的 PYTHONPATH 环境变量是否正确设置,或者尝试重置/修复你的 Python 环境。
2024-08-13



#!/usr/bin/env python
import rospy
from sensor_msgs.msg import CompressedImage
 
class ImagePublisher:
    def __init__(self):
        # 初始化节点
        rospy.init_node('image_publisher', anonymous=True)
        
        # 创建发布者,发布名为/compressed_image的CompressedImage类型消息,频率设置为10Hz
        self.publisher = rospy.Publisher('/compressed_image', CompressedImage, queue_size=10)
        
        # 设置循环的频率
        rate = rospy.Rate(10)
        
        # 设置消息数据,这里需要替换为实际的压缩图像数据
        # 假设compressed_image_data是一个包含压缩图像数据的字节串
        compressed_image_data = b'...'
        
        while not rospy.is_shutdown():
            # 创建CompressedImage消息对象
            message = CompressedImage()
            message.header.stamp = rospy.Time.now()
            message.format = "jpeg"
            message.data = compressed_image_data
            
            # 发布消息
            self.publisher.publish(message)
            
            # 等待一个循环周期
            rate.sleep()
 
if __name__ == '__main__':
    try:
        ImagePublisher()
    except rospy.ROSInterruptException:
        pass

这段代码创建了一个ROS节点,该节点负责发布名为/compressed_image的CompressedImage类型的消息。在循环中,它创建了一个CompressedImage消息对象,设置了消息头的时间戳,指定了图像的格式,并填充了图像数据。然后,该节点以10Hz的频率发布这个消息。在实际应用中,需要替换compressed_image_data为实际的压缩图像数据。