python - 关于查找两个字典交集的最佳方法的建议
问题描述
我之前发布了一个类似的问题,但是在重新设计项目之后,我来到了这里:
有两个 csv 文件(new.csv,scrapers.csv) -
scrapers.csv包含两列:
'scraper_dom' = 特定 URL 域的简化
'scraper_id' = 关联的 scraper_id,用于将 URL 导入单独管理的数据库
问题
我的目标是遍历new.csv(fnetloc
使用解析)并在scrapers.csvurlparse
上执行查找以返回一组匹配的 'scraper_id'给定一组“url”(VLOOKUP 的工作方式或 JOIN在 SQL 中),一旦在 URL 中隔离 netloc(的结果)就可以了。urlparse
fnetloc
我的下一个大问题是它urlparse
不会将 URL(来自new.csv )解析为在scrapers.csv文件中找到的精确简化,所以我将依赖于一种部分匹配,直到我能找出正则表达式用于它的那一部分。
我已经导入pandas
了,因为之前的尝试发现我创建了 DataFrames 并执行了 apd.merge
但我也无法让它工作......
当前代码,底部注释掉的位是失败的尝试,只是想我会包括我迄今为止尝试过的内容。
(##
只是print
我用来检查程序输出的中间行)
import pandas as pd, re
from urllib.parse import urlparse
import csv
sd = {}
sid = {}
#INT = []
def fnetloc(any):
try:
p = urlparse(any)
return p.netloc
except IndexError:
return 'Error'
def dom(any):
try:
r = any.split(',')
return r[0]
except IndexError:
return 'Error'
def ids(any):
try:
e = any.split(',')
return e[0]
except IndexError:
return 'Error'
with open('scrapers.csv',encoding='utf-8',newline='') as s:
reader = enumerate(csv.reader(s))
s.readline()
for j, row in reader:
dict1 = dict({'scraper_dom':dom(row[0]), 'scraper_id':ids(row[1])})
sid[j + 1] = dict1
for di in sid.keys():
id = di
##print(sid[di]['scraper_dom'],sid[di]['scraper_id'])
with open('new.csv',encoding='UTF-8',newline='') as f:
reader = enumerate(csv.reader(f))
f.readline()
for i, row in reader:
dict2 = dict({'scraper_domain': fnetloc(row[0])})
sd[i + 1] = dict2
for d in sd.keys():
id = d
##print(sd[d]['scraper_domain'])
#def tryme( ):
#return filter(sd.has_key, sid)
#print(list(filter(sid, sd.keys())))
所需输出的样本。
解决方案
您只需要一个可以获取 fnetloc 和刮板列表的过程,并检查是否有与该 fnetloc 匹配的刮板:
def fnetloc_to_scraperid(fnetloc: str, scrapers: List[Scraper]) -> str:
try:
return next(x.scraper_id for x in scrapers if x.matches(fnetloc))
except:
return "[no scraper id found]"
我还建议您使用一些类而不是将所有内容保存在 csv 行对象中——从长远来看,它可以减少代码中的错误,并大大提高您的理智。
该脚本适用于我提供给它的示例数据:
import csv
from urllib.parse import urlparse
from typing import List
def fnetloc(any) -> str:
try:
p = urlparse(any)
return p.netloc
except IndexError:
return 'Error'
class Scraper:
def __init__(self, scraper_dom: str, scraper_id: str):
self.scraper_dom = scraper_dom
self.scraper_id = scraper_id
def matches(self, fnetloc: str) -> bool:
return fnetloc.endswith(self.scraper_dom)
class Site:
def __init__(self, url: str):
self.url = url
self.fnetloc = fnetloc(url)
def get_scraperid(self, scrapers: List[Scraper]) -> str:
try:
return next(x.scraper_id for x in scrapers if x.matches(self.fnetloc))
except:
return "[no scraper id found]"
sites = [Site(row[0]) for row in csv.reader(open("new.csv"))]
scrapers = [Scraper(row[0], row[1]) for row in csv.reader(open("scrapers.csv"))]
for site in sites:
print(site.url, site.get_scraperid(scrapers), sep="\t")
推荐阅读
- mobile - 如何修复“elementsFromPoint”“提供的双精度值是无限的。” 在移动
- c++ - Wextra 的 Qt Creator 错误不起作用
- android - 当我在 android 设备上的输入元素中使用 capture="camera" 时应用程序崩溃
- excel - 单击定义为带有 SVG 的 DIV 的按钮,该 SVG 链接到带有 VBA 的路径
- java - 运行 swt java 应用程序时出错
- php - Laravel REST API 请求对象为空
- python - 如何使用pyqt4更改QScrollarea中的滚动条颜色
- firebase - Firebase 列表未在设置状态下更新
- r - 如何根据(元素)选定的相邻列计算重复的行数
- c# - ITextSharp 在词尾添加三个点