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

Scrapy如何筛选爬取包含指定文本的目标邮箱地址

Scrapy定向邮箱筛选实现

核心实现逻辑

  • 从爬取到的商家官网地址中,解析提取域名核心字段(即www.(namePart).com结构里的namePart部分),适配带/不带www、不同域名后缀的场景
  • 提取当前页面所有带邮箱的链接,自动去除mailto:前缀,统一转小写做匹配,避免大小写差异导致漏匹配
  • 按规则过滤邮箱:只要邮箱地址包含biuro、sekretariat、或者提取到的域名核心字段任意一个关键词,就判定为目标邮箱
  • 原代码仅取页面第一个邮箱的逻辑会漏判,调整为遍历全部邮箱后筛选符合规则的结果

修改后完整代码

# -*- coding: utf-8 -*-
import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy import Request, Spider
from urllib.parse import urlparse


class RynekMainSpider(scrapy.Spider):
    name = "RynekMain"
    start_urls = [
        'https://rynekpierwotny.pl/deweloperzy/?page=1']
    def parse(self, response):
        websites = response.css('div#root')[0]
        PAGETEST = response.xpath('//a[contains(@class,"rp-173nt6g")]/../following-sibling::li').css('a::attr(href)').get()
        for website in websites.css('li.rp-np9kb1'):
            page = website.css('a::attr(href)').get()
            address = website.css('address.rp-o9b83y::text').get()
            name = website.css('h2.rp-69f2r4::text').get()
            params = {
            'address' : address,
            'name' : name,
            'href' : page,
            }
            url  = response.urljoin(page)
            
            yield Request(url=url, cb_kwargs={'params': params}, callback=self.parseMain)
            
        yield Request(url=response.urljoin(PAGETEST), callback=self.parse)

    def parseMain(self, response, params=None):
        website = response.css('div.rp-l0pkv6 a::attr(href)').get()
        params['website'] = website
        urlem = response.urljoin(website)
        yield Request(url=urlem, cb_kwargs={'params': params}, callback=self.parseEmail)
        
    def parseEmail(self,response, params=None):
        # 从官网地址提取域名核心namePart
        website_url = params.get('website', '')
        domain_core = ''
        if website_url:
            parsed_url = urlparse(website_url)
            netloc = parsed_url.netloc.lower()
            # 拆分域名段,过滤www和通用后缀,取核心名称
            domain_parts = [p for p in netloc.split('.') if p not in ('www', 'com', 'pl', 'net', 'org', 'eu')]
            if domain_parts:
                domain_core = domain_parts[0]

        # 提取页面所有邮箱,统一处理格式
        raw_email_links = response.xpath('//a[contains(@href, "@")]/@href').getall()
        target_emails = []
        # 定义匹配关键词,统一转小写
        match_keywords = {'biuro', 'sekretariat'}
        if domain_core:
            match_keywords.add(domain_core.lower())

        for link in raw_email_links:
            # 去掉mailto:前缀,转小写
            email = link.replace('mailto:', '').strip().lower()
            # 只要包含任意一个目标关键词就保留
            for kw in match_keywords:
                if kw in email:
                    target_emails.append(email)
                    break # 匹配到一个关键词就停止校验当前邮箱
        
        # 去重后存入结果,多个符合条件的邮箱用分号分隔
        params['email'] = ';'.join(list(set(target_emails)))       
        yield params

if __name__ == "__main__":
    process =CrawlerProcess()
    process.crawl(RynekMainSpider)
    process.start()

补充说明

  • 域名后缀过滤列表可以根据实际爬取到的官网域名情况自行增减,比如遇到.io、.de这类后缀直接加到过滤元组里即可
  • 如果需要严格匹配邮箱前缀/后缀的规则,可以把当前的包含判断改成正则匹配,当前逻辑已经覆盖绝大多数常规筛选场景
  • 最终返回的邮箱做了去重处理,同个页面多个符合规则的邮箱会用分号拼接存储,方便后续导出处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:18:24