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

使用Scrapy爬取网站邮箱时遇请求错误,修改后仍未解决

解决Scrapy邮箱爬取器的URL错误及其他问题

核心问题分析

你遇到的Missing scheme in request url错误根源是启动URL缺少http/https协议头,同时代码还存在其他几处语法/逻辑问题,导致爬虫无法正常运行。

修正后的完整代码

import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor
from email_validator import validate_email, EmailNotValidError
import pandas as pd
import re
from urllib.parse import urlparse, urlunparse

# 修正启动URL,添加协议头
lista_star = ['https://vitalebarberiscanonico.it']

class MailSpider(scrapy.Spider):
    name = 'email'
    # 定义需要排除的链接关键词(根据需求调整)
    reject = ['facebook.com', 'twitter.com', 'instagram.com']
    # 使用实例变量存储数据,避免类变量的线程安全问题
    def __init__(self):
        self.data = []

    def parse(self, response):
        links = LxmlLinkExtractor(allow=()).extract_links(response)
        links = [str(link.url) for link in links]
        # 避免重复处理当前页面URL
        if str(response.url) not in links:
            links.append(str(response.url))

        for link in links:
            parsed_url = urlparse(link)
            # 补全协议头
            if not parsed_url.scheme:
                link = urlunparse(parsed_url._replace(scheme='https'))
            # 只保留http/https协议的链接
            elif parsed_url.scheme not in ['http', 'https']:
                continue
            # 跳过包含排除关键词的链接
            if any(word in link for word in self.reject):
                continue
            try:
                yield scrapy.Request(url=link, callback=self.parse_link)
            except Exception as e:
                self.logger.error(f"请求链接失败: {link}, 错误: {str(e)}")

    def parse_link(self, response):
        html_text = str(response.text)
        # 使用更精准的邮箱正则表达式,支持带点的用户名和多级域名
        mail_pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
        mail_list = re.findall(mail_pattern, html_text)
        
        for email in mail_list:
            # 可选:用email_validator验证邮箱有效性
            try:
                validate_email(email)
                self.data.append({'email': email, 'link': str(response.url)})
            except EmailNotValidError:
                continue

# 把get_info改为独立函数,避免类内执行顺序问题
def get_info():
    process = CrawlerProcess({
        'USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
    })
    process.crawl(MailSpider, start_urls=lista_star)
    process.start()
    
    # 从爬虫实例中获取数据(单爬虫场景下的简化处理)
    spider = next(iter(process.crawlers)).spider
    df = pd.DataFrame(spider.data)
    df = df.drop_duplicates(subset='email')
    df = df.reset_index(drop=True)
    return df

df = get_info()
# 可选:保存结果到CSV
df.to_csv('emails.csv', index=False)
print(df)

关键修改点说明

  1. 补全启动URL的协议头:直接在lista_star中添加https://,从根源解决启动时的URL scheme缺失问题。
  2. 定义self.reject变量:添加常见社交平台的排除关键词,避免爬虫爬取无关链接,可根据需求调整。
  3. 导入缺失的模块:添加re和urllib.parse模块,解决未导入导致的语法错误。
  4. 用实例变量存储数据:将data从类变量改为__init__中的实例变量,避免多线程环境下的数据冲突。
  5. 优化链接处理逻辑:
    • 补全无协议头的链接为https
    • 跳过非http/https协议的链接
    • 提前过滤包含排除关键词的链接,减少无效请求
  6. 改进邮箱正则表达式:使用更精准的正则,支持带点的用户名(如john.doe@example.com)和多级域名(如info@example.co.uk)。
  7. 添加邮箱有效性验证:利用email_validator过滤无效邮箱,避免存储错误格式的地址。
  8. 调整get_info函数位置:改为独立函数,避免类定义未完成时调用方法的问题,同时调整数据获取方式,从爬虫实例中获取data。
  9. 优化异常处理:替换裸except为捕获具体异常,并添加日志记录,方便排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:05:29