如何用Python开发爬虫实现搜索关联页面爬取及联系电话筛选提取?
Python站点联系电话抓取工具实现方案
核心实现逻辑
- 构造谷歌搜索请求,提取搜索结果页所有站点链接,按域名分组去重
- 遍历每个站点的页面,扫描锚点链接匹配联系页特征
- 跳转访问联系页,通过正则匹配提取所有格式的联系电话
- 最终按站点维度整理输出结果
前置准备
- 需提前安装依赖:
pip install requests beautifulsoup4 - 谷歌搜索有反爬机制,建议控制请求间隔在3秒以上,也可以自行更换为国内搜索引擎的搜索接口适配
- 爬取前请确认目标站点的robots协议允许抓取
完整可运行代码
import time import re import requests from urllib.parse import urlparse, urljoin from bs4 import BeautifulSoup # 配置参数 SEARCH_KEYWORD = "your search keyword here" # 替换为你要搜索的关键词 REQUEST_HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" } CONTACT_KEYWORDS = ["contact", "contact-us", "联系我们", "about", "about-us"] # 匹配国内+国际常见电话格式的正则 PHONE_PATTERN = re.compile(r'(\+?\d{1,3}[-.\s]?)?\(?\d{3,4}\)?[-.\s]?\d{3,4}[-.\s]?\d{3,4}') def get_google_search_results(keyword): """获取谷歌搜索结果,按站点分组""" site_groups = {} search_url = f"https://www.google.com/search?q={keyword}" try: resp = requests.get(search_url, headers=REQUEST_HEADERS, timeout=10) resp.raise_for_status() soup = BeautifulSoup(resp.text, 'html.parser') # 提取搜索结果所有链接 for a_tag in soup.select('a[href^="/url?q="]'): raw_url = a_tag['href'].split("/url?q=")[1].split("&")[0] parsed_url = urlparse(raw_url) domain = parsed_url.netloc if domain not in site_groups: site_groups[domain] = raw_url time.sleep(2) except Exception as e: print(f"获取谷歌搜索结果出错:{e}") return site_groups def find_contact_page_url(site_url): """查找站点的联系页链接""" try: resp = requests.get(site_url, headers=REQUEST_HEADERS, timeout=10) resp.raise_for_status() soup = BeautifulSoup(resp.text, 'html.parser') for a_tag in soup.find_all('a', href=True): href = a_tag['href'].lower() # 匹配联系页关键词 if any(key in href for key in CONTACT_KEYWORDS) and href != "#": # 相对路径转绝对路径 contact_url = urljoin(site_url, href) return contact_url time.sleep(1) except Exception as e: print(f"访问站点{site_url}出错:{e}") return None def extract_phones_from_page(page_url): """提取页面中的所有联系电话""" phones = set() try: resp = requests.get(page_url, headers=REQUEST_HEADERS, timeout=10) resp.raise_for_status() # 匹配所有符合格式的号码 matches = PHONE_PATTERN.findall(resp.text) for match in matches: # 清洗号码,去除多余符号 clean_phone = re.sub(r'[^\d+]', '', match) if 7 <= len(clean_phone) <= 15: # 过滤无效长度的号码 phones.add(clean_phone) time.sleep(1) except Exception as e: print(f"访问页面{page_url}出错:{e}") return list(phones) if __name__ == "__main__": # 1. 获取搜索结果按站点分组 site_groups = get_google_search_results(SEARCH_KEYWORD) final_result = {} # 2. 遍历每个站点找联系页提电话 for domain, site_url in site_groups.items(): print(f"正在处理站点:{domain}") contact_url = find_contact_page_url(site_url) if not contact_url: print(f"站点{domain}未找到联系页") continue phones = extract_phones_from_page(contact_url) final_result[domain] = { "site_url": site_url, "contact_url": contact_url, "phones": phones } # 3. 按站点输出结果 print("\n===== 最终抓取结果 =====") for domain, info in final_result.items(): print(f"\n站点:{domain}") print(f"官网地址:{info['site_url']}") print(f"联系页地址:{info['contact_url']}") print(f"联系电话:{','.join(info['phones']) if info['phones'] else '未找到'}")
原有代码问题修复说明
- 缺少
all_anchors定义:需要先通过soup.find_all('a', href=True)获取页面所有带有效链接的锚点标签再遍历 - 关键词判断逻辑错误:原有代码写的
if char_list in linkText,列表不能直接判断是否存在于字符串中,需要修改为if any(key in linkText.lower() for key in char_list)匹配任意关键词 - 缺少相对路径转换逻辑:联系页链接很多是相对路径,需要用
urljoin方法拼接域名得到可直接访问的绝对路径 - 缺少后续联系页访问和电话提取的逻辑,补充后即可正常运行
内容的提问来源于stack exchange,提问作者Prateek Praanjal
相关产品推荐
相关产品推荐

