如何用BeautifulSoup+Requests或Scrapy批量抓取网页内链接的内容?
批量抓取网站及所有链接内容:Requests+BeautifulSoup vs Scrapy
结论
仅用Requests+BeautifulSoup完全可以实现批量抓取,但如果要处理大量链接、追求效率或稳定性,Scrapy会是更优选择。
用Requests+BeautifulSoup实现的思路(以bleepingcomputer为例)
核心逻辑是「先抓首页解析所有站内链接 → 遍历链接逐个抓取内容」,步骤如下:
- 发送请求获取首页HTML,用BeautifulSoup解析出所有
<a>标签的href属性 - 过滤链接:只保留本站域名的链接,用集合去重避免重复抓取
- 遍历去重后的链接,逐个发送请求并解析页面内容
- 补充细节:设置请求头模拟浏览器、添加请求延迟、处理超时/异常,避免触发反爬机制
示例代码:
import requests from bs4 import BeautifulSoup import time from urllib.parse import urljoin, urlparse BASE_URL = "https://www.bleepingcomputer.com/" visited_links = set() def get_page_content(url): try: headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"} response = requests.get(url, headers=headers, timeout=10) response.raise_for_status() return response.text except Exception as e: print(f"抓取失败 {url}: {str(e)}") return None def parse_links(html, base_url): soup = BeautifulSoup(html, "html.parser") links = set() for a_tag in soup.find_all("a", href=True): full_url = urljoin(base_url, a_tag["href"]) # 仅保留本站域名的链接 if urlparse(full_url).netloc == urlparse(base_url).netloc: links.add(full_url) return links # 先抓取首页内容 home_html = get_page_content(BASE_URL) if home_html: visited_links.add(BASE_URL) all_links = parse_links(home_html, BASE_URL) # 遍历所有链接抓取内容 for link in all_links: if link not in visited_links: visited_links.add(link) print(f"正在抓取: {link}") page_content = get_page_content(link) if page_content: # 这里可根据需求修改存储逻辑,比如写入数据库或分类文件 with open(f"bleeping_{link.split('/')[-1]}.html", "w", encoding="utf-8") as f: f.write(page_content) time.sleep(1) # 添加延迟避免触发反爬
为什么推荐Scrapy?
如果要抓取的链接数量较大(上百上千个),Scrapy的优势会很突出:
- 异步并发请求:默认异步处理,比Requests的同步请求效率高很多
- 内置反爬机制:自动支持User-Agent轮换、请求延迟、失败重试等,无需手动编写大量冗余逻辑
- 完善的生态工具:自带数据管道(方便存储到数据库、文件)、爬虫中间件、断点续爬等功能
- 结构化提取更便捷:用XPath或CSS选择器可以快速定位目标内容,代码更简洁易维护
注意事项
不管用哪种方式,都要遵守目标网站的robots.txt规则,控制爬取频率,避免对网站服务器造成过大压力,防止IP被封禁。
内容的提问来源于stack exchange,提问作者ninj
相关产品推荐
相关产品推荐

