You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从CSV导入URL列表合并Python代码爬取网页数据

合并后可运行方案

你之前的代码存在三个核心问题导致运行失败:

  • 方法名拼写错误:Scrapy框架约定的初始请求入口是start_requests(末尾带s),原代码写的start_request不会被框架调用
  • 请求构造错误:Request对象单次只能接收1个URL,原代码把整个URL列表直接传入参数,无法正常发起请求
  • 逻辑冲突:两段代码分别使用Scrapy请求体系和原生urllib请求体系,混用会导致重复发请求、逻辑混乱,直接复用Scrapy自带的请求、响应处理能力即可,不需要额外写urllib相关逻辑。

前置准备

先安装依赖包:

pip install scrapy beautifulsoup4 lxml

将存储URL的urls.csv放到脚本同级目录,文件内每行填写1个目标URL即可,如果有表头请提前删除第一行。


完整代码

import re
import scrapy
from bs4 import BeautifulSoup

class ContactSpider(scrapy.Spider):
    name = "contact_spider"
    # 自定义请求头,模拟浏览器绕过反爬
    custom_headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36'
    }

    def start_requests(self):
        # 读取CSV中的所有URL,过滤空行
        with open('urls.csv', 'r', encoding='utf-8') as f:
            start_urls = [line.strip() for line in f if line.strip()]
        
        # 为每个URL单独构造请求
        for url in start_urls:
            yield scrapy.Request(
                url=url,
                headers=self.custom_headers,
                callback=self.parse,
                errback=self.err_parse, # 异常捕获,避免单个URL失败中断整个任务
                meta={'dont_redirect': False, 'handle_httpstatus_list': [404, 500, 403]}
            )

    def parse(self, response):
        current_url = response.url
        # 用BeautifulSoup提取页面纯文本,避免标签干扰正则匹配
        soup = BeautifulSoup(response.body, 'lxml')
        page_text = soup.get_text()

        # 正则匹配信息
        # 原代码的北美电话号码规则,如需匹配国内手机号可替换为r"1[3-9]\d{9}"
        phone_nums = re.findall(r"((?:\d{3}|\(\d{3}\))?(?:\s|-|\.)?\d{3}(?:\s|-|\.)\d{4})", page_text)
        # 邮箱匹配规则
        emails = re.findall(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,3}", page_text)
        # 新增6位数字国内邮编匹配规则,不需要可删除
        zip_codes = re.findall(r"\b[1-9]\d{5}(?!\d)\b", page_text)

        # 结果格式化
        result = {
            'url': current_url,
            'phone_nums': phone_nums if phone_nums else "未找到电话号码",
            'emails': emails if emails else "未找到邮箱地址",
            'zip_codes': zip_codes if zip_codes else "未找到邮编信息"
        }

        # 控制台打印结果
        print(f"\n===== 爬取结果:{current_url} =====")
        print(result)

        # 返回结果,Scrapy支持直接导出为CSV/JSON文件
        yield result

    def err_parse(self, failure):
        # 请求失败的处理
        print(f"请求失败:{failure.request.url},错误信息:{str(failure.value)}")
        yield {
            'url': failure.request.url,
            'phone_nums': "请求失败",
            'emails': "请求失败",
            'zip_codes': "请求失败"
        }

使用说明

  • 把上述代码保存到Scrapy项目的spiders目录下,运行命令scrapy crawl contact_spider -o result.csv即可自动爬取所有URL,结果会自动保存到result.csv文件中
  • 如果不需要Scrapy框架,想要纯脚本运行,可以把请求部分换成requests库实现,逻辑完全一致
  • 如果你的CSV文件带表头、URL在指定列,可以把读取CSV的部分替换为pandas读取:
    import pandas as pd
    df = pd.read_csv('urls.csv')
    start_urls = df['你的URL列名'].dropna().tolist()
    

常见问题

  • 报SSL证书错误:在Scrapy项目的settings.py中添加两行配置即可:
    DOWNLOADER_CLIENT_TLS_METHOD = 'TLSv1.2'
    SSL_CERT_FILE = False
    
  • 匹配不到内容:先打印page_text查看页面内容是否是JS动态渲染的,如果是动态加载的内容,需要集成scrapy-playwright渲染页面后再提取
  • 电话号码/邮编匹配不符合需求:直接替换对应的正则表达式即可,不影响整体逻辑

内容的提问来源于stack exchange,提问作者user19233490

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 06:06:26