Scrapy爬虫urlparse之urljoin() 必备

本文详细介绍了如何使用Python的urljoin函数将相对URL转换为绝对URL,通过具体示例展示了不同情况下的URL拼接规则,并提供了处理特殊情况的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先导入模块,用help查看相关文档

>>> from urllib import parse
>>> help(parse.urljoin)
Help on function urljoin in module urlparse:

urljoin(base, url, allow_fragments=True)
    Join a base URL and a possibly relative URL to form an absolute
    interpretation of the latter.

意思就是将基地址与一个相对地址形成一个绝对地址,然而讲的太过抽象

>>> urljoin("http://www.google.com/1/aaa.html","bbbb.html")
'http://www.google.com/1/bbbb.html'
>>> urljoin("http://www.google.com/1/aaa.html","2/bbbb.html")
'http://www.google.com/1/2/bbbb.html'
>>> urljoin("http://www.google.com/1/aaa.html","/2/bbbb.html")
'http://www.google.com/2/bbbb.html'
>>> urljoin("http://www.google.com/1/aaa.html","http://www.google.com/3/ccc.html")
'http://www.google.com/3/ccc.html'
>>> urljoin("http://www.google.com/1/aaa.html","http://www.google.com/ccc.html")
'http://www.google.com/ccc.html'
>>> urljoin("http://www.google.com/1/aaa.html","javascript:void(0)")
'javascript:void(0)'

规律不难发现,但是并不是万事大吉了,还需要处理特殊情况,如链接是其本身,链接中包含无效字符等

url = urljoin("****","****")<br><br>### find()查找字符串函数,如果查到:返回查找到的第一个出现的位置。否则,返回-1<br>if url.find("'")!=-1:<br>    continue  <br><br>### 只取井号前部分<br>url = url.split('#')[0]<br><br>### 这个isindexed()是我自己定义的函数,判断该链接不在保存链接的数据库中<br>if url[0:4]=='http' and not self.isindexed(url):<br><br>    ###newpages = set(),无序不重复元素集<br>    newpages.add(url)

原文地址:https://www.cnblogs.com/phil-chow/p/5347947.html

<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时,可用生成器替代列表推导式减少内存占用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值