将 URL 参数提取到 Pandas DataFrame

Extracting URL parameters into Pandas DataFrame

有一个列表包含 URL 个地址,参数为:

http://example.com/?param1=apple&param2=tomato&param3=carrot
http://sample.com/?param1=banana&param3=potato&param4=berry
http://example.org/?param2=apple&param3=tomato&param4=carrot

每个 URL 可能包含 4 个参数中的任何一个。

我想提取 URL 参数并将它们添加到 Pandas DataFrame 中。 DataFrame 应该有一个 URL 列和 4 个带参数的列。如果 URL 中不存在参数,则单元格为空:

URL    param1    param2     param3    param4
...    apple     tomato     carrot
...    banana               potato    berry
...              apple      tomato    carrot

我打算使用 python 内置 urlparse 模块,它可以轻松提取参数:

import urlparse
url = 'http://example.com/?param1=apple&param2=tomato&param3=carrot'
par = urlparse.parse_qs(urlparse.urlparse(url).query)
print par['param1'], par['param2']

Out: ['apple'] ['tomato']

使用 urlparse 我可以在 URLs:

中获取参数列表
import pandas as pd

urls = ['http://example.com/?param1=apple&param2=tomato&param3=carrot',
        'http://sample.com/?param1=banana&param3=potato&param4=berry',
        'http://example.org/?param2=apple&param3=tomato&param4=carrot']

df = pd.DataFrame(urls, columns=['url'])
params = [urlparse.parse_qs(urlparse.urlparse(url).query) for url in urls]
print params

Out: [{'param1': ['apple'], 'param2': ['tomato'], 'param3': ['carrot']},
      {'param1': ['banana'], 'param3': ['potato'], 'param4': ['berry']},
      {'param2': ['apple'], 'param3': ['tomato'], 'param4': ['carrot']}]
...

我不知道如何将提取的参数添加到 DataFrame 中。也许有更好的方法吗?原始文件是 ~1m URLs。

您可以使用字典理解来提取每个参数的参数中的数据。我不确定您是否想要列表形式的最终值。如果没有,提取起来很容易。

>>> pd.DataFrame({p: [d.get(p) for d in params] 
                  for p in ['param1', 'param2', 'param3', 'param4']})
     param1    param2    param3    param4
0   [apple]  [tomato]  [carrot]      None
1  [banana]      None  [potato]   [berry]
2      None   [apple]  [tomato]  [carrot]

或...

>>> pd.DataFrame({p: [d[p][0] if p in d else None for d in params] 
                  for p in ['param1', 'param2', 'param3', 'param4']})
   param1  param2  param3  param4
0   apple  tomato  carrot    None
1  banana    None  potato   berry
2    None   apple  tomato  carrot

我会推荐一个urlparse库,这种方法的好处是你不需要提前知道查询的字段名称('param1'等) :

In [278]:

import urlparse
In [279]:

T = ['http://example.com/?param1=apple&param2=tomato&param3=carrot',
     'http://sample.com/?param1=banana&param3=potato&param4=berry',
     'http://example.org/?param2=apple&param3=tomato&param4=carrot']
In [280]:

df = pd.concat(map(lambda x: pd.DataFrame(urlparse.parse_qs(urlparse.urlparse(x).query)), T))
print df
#df['URL'] = T : add another column with the original URL's
   param1  param2  param3  param4
0   apple  tomato  carrot     NaN
0  banana     NaN  potato   berry
0     NaN   apple  tomato  carrot

或者,自 pandas 0.18.0(2016 年 3 月 13 日)起,您可以将 pandas.Series.str.extractall() 方法用作:

params = df.url.str.extractall('[?&](?P<parameter>[^?#=]+)=?(?P<value>[^&]*)')
print params
Out[1]:
        parameter   value
  match                  
0 0        param1   apple
  1        param2  tomato
  2        param3  carrot
1 0        param1  banana
  1        param3  potato
  2        param4   berry
2 0        param2   apple
  1        param3  tomato
  2        param4  carrot

或者改编自那个。

如果能够(更好地)访问 urlparse 库中使用的正则表达式,以便能够在此方法中使用它们并 pandas.Series.str.extract() 直接使用它们,那就太好了。

最后,一定要收藏Working with Text Data,里面有很多有用的例子。