import requests from urllib.parse import urlparse, urljoin from bs4 import BeautifulSoup def extract_internal_links(base_url, max_depth=2): visited = set() internal_links = set() def crawl(url, current_depth): if current_depth > max_depth or url in visited: return visited.add(url) try: response = requests.get(url, timeout=5) if response.status_code != 200: return soup = BeautifulSoup(response.text, 'html.parser') for a_tag in soup.find_all('a', href=True): href = a_tag['href'] full_url = urljoin(url, href) parsed_url = urlparse(full_url) # 清除锚点和空路径 clean_url = parsed_url._replace(fragment='', query='').geturl() # 筛选同域名非文件链接 if parsed_url.netloc == urlparse(base_url).netloc: if not clean_url.endswith(('pdf', 'jpg', 'png')): internal_links.add(clean_url) crawl(clean_url, current_depth + 1) except (requests.exceptions.RequestException, UnicodeEncodeError): pass crawl(base_url, 0) return internal_links # 使用示例 if __name__ == "__main__": target_url = "https://www.dpm.org.cn/collection/embroiders.html" links = extract_internal_links(target_url) print(f"发现 {len(links)} 个内部链接:") for link in links: print(link) 我现在通过此代码爬取出一些链接 现在我想将这些链接判断是否包含一些关键词 若包含该关键词 则将这些链接放入列表 否则舍去
时间: 2025-07-11 11:33:59 浏览: 5
<think>好的,我现在需要解决用户的问题:如何根据关键词过滤爬取到的URL,并将符合条件的链接存入列表。首先,我需要理清用户的需求。用户可能是在进行网络爬虫开发,爬取了大量链接,但只想保留包含特定关键词的那些,比如和“科技”或“新闻”相关的链接。这需要从爬取的URL列表中筛选出包含这些关键词的链接,并存储起来。
接下来,我得考虑实现这一功能的具体步骤。根据用户提供的引用,特别是引用[1]和引用[2],用户之前可能已经使用过类似Scrapy或BeautifulSoup这样的库进行爬取,并且已经处理过URL去重的问题。现在需要扩展功能,增加关键词过滤。首先,我需要确定如何从URL中提取关键词。通常,URL包含路径、查询参数等部分,可能需要检查整个URL字符串是否包含特定关键词,或者是否在特定部分出现。
然后,我需要考虑如何高效地进行关键词匹配。比如,用户可能有多个关键词,需要任何一个关键词出现在URL中就保留该链接。或者需要同时满足多个关键词。这里可能需要使用字符串的in操作符,或者正则表达式来匹配。考虑到性能,如果URL数量很大,可能需要优化匹配方式,比如预处理关键词,或者使用更高效的数据结构。
接下来,根据用户提供的引用[3]和引用[4],用户可能已经将数据存入数据库,比如MongoDB。因此,过滤后的链接可能需要存入数据库中的某个表,或者先存入列表再批量插入。需要确保在存入时进行去重,避免重复数据。引用[1]中提到使用url去重,可能通过数据库的唯一索引或内存中的集合来实现。
然后,我需要参考用户提供的代码示例,比如引用[1]中的Python代码,可能涉及循环处理每个URL,检查是否包含关键词,然后添加到列表中。例如,可以遍历爬取到的所有URL,对每个URL使用if判断,如果任何关键词在URL中,则保留。此外,用户可能需要处理不同大小写的情况,是否需要转换为统一的大小写再进行匹配,比如将URL和关键词都转为小写。
另外,可能还需要考虑URL的编码问题,比如某些关键词可能在URL中被编码,比如空格变成%20,这时候直接匹配可能失效。因此,是否需要先对URL进行解码,再进行匹配?不过这可能增加处理步骤,影响效率,需要根据具体情况权衡。
接下来,代码实现方面,假设用户已经有一个URL列表,可以通过列表推导式来过滤。例如:
filtered_urls = [url for url in all_urls if any(keyword in url for keyword in keywords)]
这里的关键词列表keywords由用户提供。但需要注意,这种方式是大小写敏感的,如果用户希望不区分大小写,可能需要将url和keyword都转换为小写:
filtered_urls = [url for url in all_urls if any(keyword.lower() in url.lower() for keyword in keywords)]
不过,这样的处理可能会影响性能,尤其是当URL和关键词数量很大时。需要提醒用户根据实际需求调整。
此外,如果用户需要更复杂的匹配规则,比如关键词出现在特定位置(如路径中、查询参数中等),可能需要解析URL的结构,使用urllib.parse模块来分解URL的不同部分,然后针对特定部分进行检查。例如:
from urllib.parse import urlparse
parsed_url = urlparse(url)
path = parsed_url.path
query = parsed_url.query
然后检查path或query中是否包含关键词。这可能更精确,但也会增加代码复杂度。
关于存入列表,用户可能需要将过滤后的URL存入数据库,如引用[4]中的MongoDB。这时候可以在过滤后,遍历filtered_urls,逐个插入数据库,同时确保去重。例如,在插入前检查数据库中是否已存在该URL,或者使用唯一索引避免重复。
最后,需要考虑异常处理,比如URL格式不正确的情况,或者在匹配过程中出现错误。可能需要添加try-except块来捕获异常,确保程序稳定运行。
总结步骤大致如下:
1. 获取所有爬取到的URL列表。
2. 定义需要过滤的关键词列表。
3. 遍历每个URL,检查是否包含任一关键词。
4. 将符合条件的URL存入新的列表。
5. 对列表进行去重处理(如果需要)。
6. 将最终列表存入数据库或文件。
可能还需要优化性能,比如使用生成器表达式处理大量数据,或者并行处理URL的过滤。但根据用户提供的引用,他们可能更倾向于简单直接的实现,所以保持代码简洁易懂更重要。
在示例代码中,用户可能使用类似引用[1]的结构,添加过滤逻辑。例如,在爬取到URL后立即进行过滤,或者在存储前进行批量过滤。同时,结合引用[3]中的代理处理方式,可能需要对URL进行预处理,比如去除多余参数或标准化URL格式,以提高关键词匹配的准确性。
最后,需要测试代码的正确性,确保所有包含关键词的URL都被正确过滤,并且没有遗漏或误判。可以使用单元测试或手动测试几个案例来验证。</think>### 根据关键词过滤URL的实现步骤
#### 1. 定义关键词列表
首先明确需要过滤的关键词,例如`keywords = ["科技", "news", "sports"]`。
#### 2. 遍历爬取的URL列表并过滤
使用列表推导式快速筛选包含关键词的URL:
```python
# 假设 all_urls 是爬取到的原始URL列表
keywords = ["科技", "news", "sports"]
filtered_urls = [
url
for url in all_urls
if any(keyword in url for keyword in keywords)
]
```
若需不区分大小写,可优化为:
```python
filtered_urls = [
url
for url in all_urls
if any(keyword.lower() in url.lower() for keyword in keywords)
]
```
#### 3. URL去重处理
通过集合(Set)特性自动去重,例如:
```python
filtered_urls = list(set(filtered_urls)) # 简单去重
```
或结合数据库唯一索引(如引用[1]中SQL去重逻辑):
```python
# 假设已连接数据库,table为存储表对象
for url in filtered_urls:
if not table.exists(where("url") == url): # 伪代码,具体取决于数据库类型
table.insert({"url": url, ...})
```
#### 4. 存入数据库(以MongoDB为例)
参考引用[4]中的方法,使用`pymongo`库:
```python
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client['news_db']
collection = db['filtered_urls']
# 批量插入并去重
for url in filtered_urls:
if not collection.find_one({"url": url}):
collection.insert_one({"url": url, "status": "unprocessed"})
```
#### 5. 完整代码示例
```python
from urllib.parse import urlparse
import pymongo
def filter_urls(all_urls, keywords):
# 过滤URL(包含大小写处理)
filtered = [
url
for url in all_urls
if any(kw.lower() in url.lower() for kw in keywords)
]
# 去重
filtered = list(set(filtered))
return filtered
def save_to_mongodb(url_list):
client = pymongo.MongoClient('mongodb://localhost:27017/')
db = client['crawler_db']
collection = db['target_urls']
for url in url_list:
if not collection.find_one({"url": url}):
collection.insert_one({
"url": url,
"timestamp": datetime.now()
})
# 使用示例
all_urls = ["http://news.com/tech", "http://sports.cn/match", ...] # 爬取的原始URL
keywords = ["tech", "科技", "sports"]
result = filter_urls(all_urls, keywords)
save_to_mongodb(result)
```
#### 注意事项
1. **编码问题**:若URL包含特殊字符(如`%20`表示空格),需先解码再匹配,例如:
```python
from urllib.parse import unquote
decoded_url = unquote(url)
```
2. **精准匹配**:若需关键词出现在特定位置(如路径或域名),可结合`urlparse`解析:
```python
parsed = urlparse(url)
if "news" in parsed.path: # 检查路径部分
...
```
3. **性能优化**:处理海量URL时,可用生成器替代列表推导式减少内存占用。
阅读全文
相关推荐

















