首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >用 Python 采集文章数据并下载图片上传到腾讯云 COS

用 Python 采集文章数据并下载图片上传到腾讯云 COS

原创
作者头像
用户2695996
发布2025-12-05 17:34:19
发布2025-12-05 17:34:19
2890
举报
文章被收录于专栏:源码搭建源码搭建

在数据挖掘、内容聚合或 AI 训练场景中,我们经常需要从网页批量采集文章及其配图。本文将演示如何使用 Python:

  1. 爬取文章列表与详情页
  2. 提取标题、正文和图片链接
  3. 下载本地图片
  4. 自动上传至腾讯云 COS(对象存储)

⚠️ 注意:本文仅用于技术学习,请遵守目标网站 robots.txt 及《网络安全法》,禁止用于商业侵权或高频爬取。


一、环境准备

安装所需库:

代码语言:javascript
复制
pip install requests beautifulsoup4 lxml cos-python-sdk-v5 pillow
  • requests:发送 HTTP 请求
  • beautifulsoup4:解析 HTML
  • cos-python-sdk-v5:腾讯云 COS 官方 SDK
  • Pillow(可选):用于图片格式校验

二、获取腾讯云 COS 配置

  1. 登录 腾讯云控制台
  2. 创建存储桶(如 dream-data-1250000000),地域选 ap-beijing
  3. 获取 SecretIdSecretKey(访问管理 → API 密钥)
  4. 记录 Bucket 名称Region

三、完整 Python 代码实现

代码语言:javascript
复制
import os
import time
import requests
from bs4 import BeautifulSoup
from qcloud_cos import CosConfig, CosS3Client
import logging

# === 腾讯云 COS 配置 ===
secret_id = '你的 SecretId'
secret_key = '你的 SecretKey'
region = 'ap-beijing'  # 存储桶地域
bucket = 'dream-data-1250000000'  # 替换为你的 Bucket 名称(不含地域后缀)

# 初始化 COS 客户端
config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key)
cos_client = CosS3Client(config)

# 创建本地临时目录
os.makedirs('temp_images', exist_ok=True)

# === 工具函数 ===
def download_image(url, filename):
    """下载图片到本地"""
    try:
        resp = requests.get(url, timeout=10)
        if resp.status_code == 200:
            filepath = os.path.join('temp_images', filename)
            with open(filepath, 'wb') as f:
                f.write(resp.content)
            return filepath
    except Exception as e:
        print(f"下载失败 {url}: {e}")
        return None

def upload_to_cos(local_path, cos_key):
    """上传文件到 COS"""
    try:
        response = cos_client.upload_file(
            Bucket=bucket,
            LocalFilePath=local_path,
            Key=cos_key,
            EnableMD5=False
        )
        print(f"✅ 上传成功: {cos_key}")
        return f"https://{bucket}.cos.{region}.myqcloud.com/{cos_key}"
    except Exception as e:
        print(f"❌ 上传失败 {local_path}: {e}")
        return None

# === 主采集逻辑 ===
def scrape_jixing_articles():
    base_url = "https://www.jixing.net"
    index_url = "https://www.jixing.net/jiemeng/"

    print("正在抓取文章列表...")
    resp = requests.get(index_url, headers={'User-Agent': 'Mozilla/5.0'})
    soup = BeautifulSoup(resp.text, 'lxml')

    # 提取文章链接(根据实际页面结构调整)
    article_links = []
    for item in soup.select('.list-item a'):  # 假设文章链接在 .list-item 下
        href = item.get('href')
        if href and href.startswith('/jiemeng/'):
            full_url = base_url + href
            article_links.append(full_url)

    print(f"共找到 {len(article_links)} 篇文章")

    for idx, url in enumerate(article_links[:5]):  # 限制前5篇测试
        print(f"\n--- 处理第 {idx+1} 篇: {url} ---")
        try:
            detail_resp = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'})
            detail_soup = BeautifulSoup(detail_resp.text, 'lxml')

            title = detail_soup.select_one('h1') or detail_soup.select_one('.title')
            title_text = title.get_text(strip=True) if title else f"article_{idx}"

            content_div = detail_soup.select_one('.content') or detail_soup.select_one('.article-content')
            if not content_div:
                print("未找到正文区域,跳过")
                continue

            # 提取所有图片
            images = content_div.find_all('img')
            new_img_urls = []

            for i, img in enumerate(images):
                src = img.get('src') or img.get('data-src')
                if not src:
                    continue

                # 补全绝对路径
                if src.startswith('/'):
                    img_url = base_url + src
                elif src.startswith('http'):
                    img_url = src
                else:
                    continue

                # 生成唯一文件名
                ext = os.path.splitext(src.split('?')[0])[1] or '.jpg'
                filename = f"{title_text[:20].replace('/', '_')}_{i}{ext}"
                local_path = download_image(img_url, filename)

                if local_path:
                    cos_key = f"jiemeng/{filename}"
                    cos_url = upload_to_cos(local_path, cos_key)
                    if cos_url:
                        new_img_urls.append(cos_url)
                        # 替换原 img 标签 src(可选)
                        img['src'] = cos_url

            # 保存处理后的 HTML 或打印结果
            print(f"标题: {title_text}")
            print(f"替换图片数: {len(new_img_urls)}")
            print("新图片 CDN 地址:", new_img_urls)

            # 可选:将处理后的 HTML 保存或入库
            # with open(f"output/{title_text[:20]}.html", "w", encoding="utf-8") as f:
            #     f.write(str(content_div))

            time.sleep(1)  # 礼貌爬取

        except Exception as e:
            print(f"处理失败: {e}")
            continue

if __name__ == '__main__':
    scrape_jixing_articles()

四、关键说明

1. 页面结构适配

吉星堂网站的 HTML 结构可能随时间变化,请根据实际页面调整选择器:

  • 文章列表容器:.list-item a
  • 标题:h1.title
  • 正文:.content.article-content

可通过浏览器开发者工具(F12)查看具体 class。

2. 图片路径处理

  • 自动补全相对路径(如 /upload/xxx.jpghttps://www.jixing.net/upload/xxx.jpg
  • 支持 data-src 懒加载属性(部分网站使用)

3. 腾讯云 COS 上传

  • 上传后返回 CDN 地址,可直接用于 Web 展示
  • 文件按 jiemeng/ 目录组织,便于管理

4. 合规建议

  • 添加 time.sleep(1) 避免请求过快
  • 设置合理 User-Agent
  • 仅采集公开内容,不破解反爬

五、后续扩展

  • 将文章元数据(标题、URL、COS 图片列表)存入 MySQL 或 MongoDB
  • 使用 Scrapy 框架实现分布式采集
  • 添加异常重试与日志监控
  • 自动压缩图片以节省存储成本

结语

通过本文,你已掌握从目标网站采集文章、下载图片并上传至腾讯云 COS 的完整流程。这不仅适用于解梦类网站,也可迁移到新闻、博客、电商等场景。

🌟 技术无罪,善用为要。请始终尊重网站版权与服务器资源。


欢迎各位朋友继续交流python如何采集数据等问题!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、环境准备
  • 二、获取腾讯云 COS 配置
  • 三、完整 Python 代码实现
  • 四、关键说明
    • 1. 页面结构适配
    • 2. 图片路径处理
    • 3. 腾讯云 COS 上传
    • 4. 合规建议
  • 五、后续扩展
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档