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

网页爬虫正则提取邮箱失败求助(电话提取功能正常)

解决方案:修复邮箱提取问题

问题根源分析

你的邮箱提取失败主要有两个核心原因:

  1. 正则表达式转义错误:你使用的"\b..."是普通字符串,其中\b会被Python解析为退格符,而非正则表达式的单词边界。
  2. 网页邮箱的存在形式多样:很多网站不会直接把邮箱明文放在文本节点中,而是藏在mailto:链接的属性里,或者用HTML实体编码、JavaScript动态生成。

具体修复步骤

1. 修正正则表达式

使用原始字符串定义正则(前缀r),避免转义冲突,同时修正字符类的错误:

# 修正后的邮箱正则:用原始字符串,去掉多余的|符号
mail_regex = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,7}\b"

2. 提取多种形式的邮箱

除了匹配文本节点,还要处理mailto:链接、HTML编码的邮箱:

修改后的完整代码

import requests
from bs4 import BeautifulSoup
import re
from html import unescape

def extract_contact_info(url):
    address_t = []
    phone_num_t = []
    email_t = []

    # 发送请求
    response = requests.get(url)
    soup = BeautifulSoup(response.content, "html.parser")

    # 提取电话号码
    phone_regex = r"(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}"
    phone_matches = soup.find_all(string=re.compile(phone_regex))
    if phone_matches:
        phone_num_t.extend([match.strip() for match in phone_matches])
        print("找到电话号码:", phone_num_t)
    else:
        print("未找到电话号码")

    # 提取邮箱:处理三种情况
    mail_regex = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,7}\b"

    # 情况1:匹配文本节点中的明文邮箱
    text_matches = soup.find_all(string=re.compile(mail_regex))
    email_t.extend([match.strip() for match in text_matches])

    # 情况2:提取mailto链接中的邮箱
    mailto_links = soup.find_all("a", href=re.compile(r"^mailto:"))
    for link in mailto_links:
        email = link["href"].replace("mailto:", "").strip()
        # 解码可能的HTML实体
        email = unescape(email)
        if re.match(mail_regex, email):
            email_t.append(email)

    # 情况3:解码HTML实体后匹配(处理编码的邮箱)
    all_text = soup.get_text()
    decoded_text = unescape(all_text)
    encoded_matches = re.findall(mail_regex, decoded_text)
    email_t.extend([match.strip() for match in encoded_matches])

    # 去重
    email_t = list(set(email_t))
    if email_t:
        print("找到邮箱:", email_t)
    else:
        print("未找到邮箱")

    return address_t, phone_num_t, email_t

# 测试目标网站
extract_contact_info('https://www.zimmermanfinancialgroup.com/about')
extract_contact_info('https://www.benefitexperts.com/about-us/')

3. 处理动态加载的邮箱(可选)

如果上述方法仍无法提取,说明邮箱是通过JavaScript动态渲染的,此时需要使用浏览器渲染工具(如Selenium):

from selenium import webdriver
from selenium.webdriver.common.by import By
import time

def extract_dynamic_email(url):
    driver = webdriver.Chrome()
    driver.get(url)
    time.sleep(2)  # 等待页面加载

    # 获取页面所有文本
    page_text = driver.find_element(By.TAG_NAME, "body").text
    mail_regex = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,7}\b"
    emails = re.findall(mail_regex, page_text)

    # 提取mailto链接
    mailto_elements = driver.find_elements(By.CSS_SELECTOR, "a[href^='mailto:']")
    for elem in mailto_elements:
        email = elem.get_attribute("href").replace("mailto:", "").strip()
        emails.append(email)

    emails = list(set(emails))
    print("动态页面找到邮箱:", emails)
    driver.quit()
    return emails

关键说明

  • 原始字符串:使用r""定义正则可以避免Python对反斜杠的自动转义,确保正则语法正确。
  • 去重处理:同一邮箱可能在多个位置出现,用list(set(email_t))去重。
  • HTML实体解码:html.unescape()可以把a这类编码转成正常字符,解决邮箱被编码的问题。
  • 动态内容处理:如果网站用JS加载邮箱,必须用浏览器渲染工具获取完整页面内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:17:25