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
相关产品推荐
相关产品推荐

