通用网页爬虫脚本调试求助:输出文件为空问题
解决爬虫输出空DOCX及通用爬虫构建方案
一、空DOCX问题的核心排查方向(无代码情况下的通用要点)
- 请求被反爬拦截:CNN有反爬机制,直接用
requests.get可能返回空页面或403状态码。必须添加模拟浏览器的请求头(User-Agent、Accept等),必要时用Session维持会话。 - 内容提取逻辑错误:即使拿到页面,若XPath/CSS选择器写错,会导致无法抓取含"mccarthy"的内容。建议先把爬取到的页面存为HTML文件,打开确认是否和浏览器显示内容一致。
- DOCX写入逻辑漏洞:使用
python-docx时,若未正确调用document.add_paragraph()添加内容,或document.save()放在了错误位置(比如循环外未执行),都会导致文件为空。
二、通用爬虫的构建思路(适配多网站+复杂搜索)
1. 模块化拆分
将爬虫拆分为独立模块,后续适配新网站只需修改对应模块:
- 请求模块:封装请求逻辑,处理反爬(延迟、请求头切换),传入URL即可返回页面内容。
- 解析模块:针对不同网站编写解析函数,用配置文件(如JSON)存储各网站的选择器规则,无需改动核心代码。
- 存储模块:单独处理DOCX/CSV等存储逻辑,只要传入解析后的结构化数据即可完成存储。
2. 支持复杂搜索字符串
- 用
urllib.parse.quote()将含空格、特殊字符的搜索词转为URL编码格式,避免请求报错。 - 针对多关键词组合(如"mccarthy AND congress"),根据目标网站的搜索规则拼接对应的搜索URL(比如CNN用
q参数,百度用wd参数)。
3. 基础反爬处理
- 随机切换
User-Agent,避免被识别为固定爬虫。 - 添加随机延迟(
time.sleep(random.uniform(1,3))),降低请求频率。 - 若目标网站内容为JS动态渲染,替换
requests为Selenium或Playwright获取页面源码。
三、CNN爬虫示例代码(含DOCX输出)
import requests from bs4 import BeautifulSoup from docx import Document import urllib.parse import time import random # 请求模块:处理页面获取与反爬 def fetch_page(url, headers): try: time.sleep(random.uniform(1, 2)) response = requests.get(url, headers=headers) response.raise_for_status() # 抛出HTTP错误 return response.text except Exception as e: print(f"请求失败: {str(e)}") return None # 解析模块:CNN搜索结果页解析 def parse_cnn_search(html, keyword): soup = BeautifulSoup(html, 'html.parser') results = [] # 注意:CNN页面元素可能更新,需自行检查调整选择器 for item in soup.select('.cnn-search__result-contents'): title_elem = item.select_one('.cnn-search__result-headline a') snippet_elem = item.select_one('.cnn-search__result-body') title = title_elem.get_text(strip=True) if title_elem else '' snippet = snippet_elem.get_text(strip=True) if snippet_elem else '' # 过滤含关键词的结果 if keyword.lower() in title.lower() or keyword.lower() in snippet.lower(): results.append({'title': title, 'snippet': snippet}) return results # 存储模块:结构化数据写入DOCX def save_to_docx(data, filename): doc = Document() if not data: doc.add_paragraph("未找到匹配内容") else: for idx, item in enumerate(data, 1): doc.add_heading(f"搜索结果 {idx}", level=2) doc.add_paragraph(f"标题: {item['title']}") doc.add_paragraph(f"摘要: {item['snippet']}") doc.add_paragraph("---") doc.save(filename) # 主逻辑 if __name__ == "__main__": keyword = "mccarthy" # 构造CNN搜索URL encoded_keyword = urllib.parse.quote(keyword) search_url = f"https://www.cnn.com/search?q={encoded_keyword}" # 模拟浏览器请求头 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' } html = fetch_page(search_url, headers) if html: parsed_data = parse_cnn_search(html, keyword) save_to_docx(parsed_data, "cnn_mccarthy_results.docx") print("结果已保存至DOCX文件") else: print("未成功获取页面内容")
四、适配其他网站的注意事项
- 新增
parse_xxx()函数,替换为目标网站的CSS选择器/XPath规则。 - 调整搜索URL的构造方式,不同网站的搜索参数格式不同(如谷歌用
q,知乎用q,豆瓣用search_text)。 - 若目标网站为动态渲染,将
fetch_page()替换为Selenium实现:
from selenium import webdriver def fetch_page_selenium(url): driver = webdriver.Chrome() driver.get(url) html = driver.page_source driver.quit() return html
内容的提问来源于stack exchange,提问作者Mark J. Flowers
相关产品推荐
相关产品推荐

