如何调用自定义URL类为Pandas DataFrame创建新列
原代码问题说明
你定义的URL类中run方法存在设计逻辑问题:该方法属于实例方法,仅会绑定初始化时传入的单个URL对象,但方法内部却尝试处理整个DataFrame的URL列,无法直接调用生效。以下是两种可直接落地的调用方案:
方案1:仅计算URL熵(无需发起HTTP请求)
URL熵的计算仅依赖URL字符串本身,不需要发起网络请求,可以直接抽离逻辑调用,执行效率更高:
import math import pandas as pd # 抽离熵计算逻辑为独立函数 def calculate_entropy(url): string = url.strip() prob = [float(string.count(c)) / len(string) for c in dict.fromkeys(list(string))] entropy = sum([(p * math.log(p) / math.log(2.0)) for p in prob]) return entropy # 直接生成新列 df['entropy'] = df['url_without_parameters'].apply(calculate_entropy)
方案2:需要同时计算URL熵、页面body长度等需HTTP请求的字段
如果需要用到页面内容相关的计算,需要对每个URL实例化,同时补充异常捕获避免请求失败中断流程:
import requests from pyquery import PyQuery import math import pandas as pd # 优化原URL类,新增异常捕获 class URL(object): def __init__(self, url): self.url = url self.domain = url.split('//')[-1].split('/')[0] # 处理请求超时、无效URL等异常情况 try: self.response = requests.get(self.url, timeout=10) self.pq = PyQuery(self.response.text) except Exception as e: self.response = None self.pq = None def entropy(self): string = self.url.strip() prob = [float(string.count(c)) / len(string) for c in dict.fromkeys(list(string))] entropy = sum([(p * math.log(p) / math.log(2.0)) for p in prob]) return entropy def bodyLength(self): if self.pq is not None: return len(self.pq('html').text()) else: return 0 # 封装单URL处理函数 def process_single_url(url): url_obj = URL(url) # 可按需返回更多字段 return pd.Series([url_obj.entropy(), url_obj.bodyLength()]) # 批量生成多列新字段 df[['entropy', 'body_length']] = df['url_without_parameters'].apply(process_single_url)
注意事项
- 单线程逐行发起HTTP请求速度较慢,如果URL数量较多,建议搭配线程池做并发优化
- 你之前用到的
np.vectorize本质还是串行循环,和apply性能差异不大,apply写法可读性更高
内容的提问来源于stack exchange,提问作者bisoubisou
相关产品推荐
相关产品推荐

