from bs4 import BeautifulSoup import requests import re #自定义队列类 class linkQuence: def __init__(self): # 已访问的url集合 self.visted = [] # 待访问的url集合 self.unVisited = [] # 获取访问过的url队列 def getVisitedUrl(self): return self.visted # 获取未访问的url队列 def getUnvisitedUrl(self): return self.unVisited # 添加到访问过得url队列中 def addVisitedUrl(self, url): self.visted.append(url) # 移除访问过得url def removeVisitedUrl(self, url): self.visted.remove(url) # 未访问过得url出队列 def unVisitedUrlDeQuence(self): try: return self.unVisited.pop() except: return None # 保证每个url只被访问一次 def addUnvisitedUrl(self, url): if url != "" and url not in self.visted and url not in self.unVisited: self.unVisited.insert(0, url) # 获得已访问的url数目 def getVisitedUrlCount(self): return len(self.visted) # 获得未访问的url数目 def getUnvistedUrlCount(self): return len(self.unVisited) # 判断未访问的url队列是否为空 def unVisitedUrlsEnmpy(self): return len(self.unVisited) == 0 class MyCrawler: def __init__(self, seeds): # 初始化当前抓取的深度 self.current_deepth = 1 # 使用种子初始化url队列 self.linkQuence = linkQuence() if isinstance(seeds, str): self.linkQuence.addUnvisitedUrl(seeds) if isinstance(seeds, list): for i in seeds: self.linkQuence.addUnvisitedUrl(i) # 抓取过程主函数 def crawling(self, seeds, crawl_deepth): # ********** Begin **********# # ********** End **********# # 获取源码中得超链接 def getHyperLinks(self, url): # ********** Begin **********# # ********** End **********# # 获取网页源码 def getPageSource(self, url): # ********** Begin **********# # ********** End **********# def main(seeds="http://www.baidu.com", crawl_deepth=3): craw = MyCrawler(seeds) craw.crawling(seeds, crawl_deepth) return craw.linkQuence.getVisitedUrl()
时间: 2025-05-27 13:27:18 浏览: 20
### 方法实现
以下是 `MyCrawler` 类中三个核心方法的实现:`crawling`、`getHyperLinks` 和 `getPageSource`。
#### 1. crawling 方法
此方法用于执行整个爬虫流程,包括 URL 去重和页面抓取。它会调用其他两个辅助方法来获取超链接并保存页面源码。
```python
import requests
from bs4 import BeautifulSoup
from pybloom_live import ScalableBloomFilter
class MyCrawler:
def __init__(self, initial_url_list):
self.bloom_filter = ScalableBloomFilter(initial_capacity=100000, error_rate=0.001)
self.urls_to_crawl = initial_url_list
def crawling(self):
while self.urls_to_crawl:
url = self.urls_to_crawl.pop(0)
if url in self.bloom_filter:
print(f"URL already crawled: {url}")
continue
try:
page_source = self.getPageSource(url)
hyperlinks = self.getHyperLinks(page_source)
# 添加当前 URL 到布隆过滤器
self.bloom_filter.add(url)
# 将新发现的 URL 加入待爬队列
for link in hyperlinks:
if link not in self.bloom_filter and link.startswith("http"):
self.urls_to_crawl.append(link)
# 可在此处处理页面数据 (存储或进一步分析)
with open(f"{hash(url)}.html", "w", encoding="utf-8") as f:
f.write(page_source)
except Exception as e:
print(f"Error processing URL {url}: {e}")
```
#### 2. getHyperLinks 方法
该方法负责从给定的 HTML 页面中提取所有的超链接地址。
```python
def getHyperLinks(self, html_content):
soup = BeautifulSoup(html_content, 'html.parser')
links = []
for a_tag in soup.find_all('a', href=True):
links.append(a_tag['href'])
return links
```
#### 3. getPageSource 方法
这个方法用来请求指定 URL 的内容,并返回完整的页面源代码字符串形式。
```python
def getPageSource(self, url):
headers = {'User-Agent': 'Mozilla/5.0'} # 设置 User-Agent 防止被拒绝访问
response = requests.get(url, headers=headers)
if response.status_code != 200:
raise ValueError(f"Failed to retrieve content from {url}. Status code: {response.status_code}")
return response.text
```
以上实现了基本的功能需求[^1],其中包含了 URL 去重机制以及简单的错误处理逻辑[^2]。需要注意的是,在实际应用过程中可能还需要考虑更多细节问题比如编码转换、异常情况下的重试策略等[^3]。
另外值得注意的一点是,某些情况下目标站点可能会加载由 JavaScript 动态生成的内容,单纯依靠 Requests 库加上 Beautiful Soup 是无法解决这类难题的;此时可以引入 Selenium 工具作为补充方案之一[^4]^。
最后提醒一下关于异步操作方面如果有更高性能的要求的话,则建议采用 aiohttp 结合 asyncio 来构建更加高效的版本[^5]。
---
###
阅读全文
相关推荐


















