【问题标题】:Parsing Alexa for rank info解析 Alexa 以获取排名信息
【发布时间】:2020-01-05 20:18:30
【问题描述】:

我想从 Alexa 中提取与 <REACH RANK="1"/> 关联的整数。我的意思:

<!--
    Need more Alexa data?  Find our APIS here: https://aws.amazon.com/alexa/
-->
<ALEXA VER="0.9" URL="google.com/" HOME="0" AID="=" IDN="google.com/">
  <SD TITLE="A" FLAGS="" HOST="google.com">
    <OWNER NAME="aa"/>
  </SD>
  <SD>
    <POPULARITY URL="google.com/" TEXT="1" SOURCE="panel"/>
    <REACH RANK="1"/>
    <RANK DELTA="+0"/> 
    <COUNTRY CODE="US" NAME="United States" RANK="1"/>
  </SD>
</ALEXA>

到目前为止,我尝试过的是来自 Github 帖子的建议,并在尝试使用所述正则表达式模式的不同代码变体时混淆了 RegExr 上的正则表达式模式。

我目前拥有的:

 try:
    xml = (BeautifulSoup(urllib.request.urlopen("http://data.alexa.com/data?cli=10&dat=snbamz&url=" + url).read(), "xml"))

    rank = re.search(r'"<REACH[^>]*RANK="(\d+")', xml)
    print(rank)
    print(f'Your rank for {url} is {rank}')
 except Exception as err:
    print(err)
    rank = -1
    #print(f'Your rank for {url} is {rank}')

它要么 1) 命中异常,要么 2) 导致此错误:

expected string or bytes-like object

【问题讨论】:

  • 不要使用正则表达式解析结构化格式。这是 XML;使用 XML 解析器。 BeautifulSoup 包含用于提取 XPath 表达式的有用代码。

标签: regex python-3.x xml beautifulsoup


【解决方案1】:

由于您使用的是 BeautifulSoup,您可以使用 xml 解析它。像这样的:

import requests
from bs4 import BeautifulSoup

endpoint = 'http://data.alexa.com/data'

url = 'insert the value you are using here'

data = dict(
    cli=10,
    dat=snbamz,
    url=url
)

r = requests.get(url, data=data)

soup = BeautifulSoup(r.content, 'xml')

rank = soup.REACH.get('RANK')

这不是一个完整的例子,但我希望它可以作为你可以从那里开发的起点。

这是一个概念证明:

Python 3.7.5 (default, Dec 15 2019, 17:54:26) 
[GCC 9.2.1 20190827 (Red Hat 9.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from bs4 import BeautifulSoup
>>> alexa = '''
... <!--
...     Need more Alexa data?  Find our APIS here: https://aws.amazon.com/alexa/
... -->
... <ALEXA VER="0.9" URL="google.com/" HOME="0" AID="=" IDN="google.com/">
...   <SD TITLE="A" FLAGS="" HOST="google.com">
...     <OWNER NAME="aa"/>
...   </SD>
...   <SD>
...     <POPULARITY URL="google.com/" TEXT="1" SOURCE="panel"/>
...     <REACH RANK="1"/>
...     <RANK DELTA="+0"/> 
...     <COUNTRY CODE="US" NAME="United States" RANK="1"/>
...   </SD>
... </ALEXA>
... '''
>>> soup = BeautifulSoup(alexa, 'xml')
>>> rank = soup.REACH.get('RANK')
>>> rank
'1'
>>>

【讨论】:

  • 谢谢,这正是我想要完成的。我的另一个问题是,如果我在同一个 Python 文档中使用 BS 来解析不同的网站,尽管所有声明的 soups 都在不同的 try 块内,我可以继续在同一个中重新声明 soup如果我有意义的话,Python文件同时保持汤的完整性?所以,try: soup = ... except: ... 15 行代码之后:try: soup = ... except: ...
  • 我很确定你会在每次通话时覆盖soup。如果您需要保留所有这些,只需使用列表即可。像soups = [] 这样的东西,然后,在每个块上,soups.add(BeautifulSoup(next_xml, 'xml'))。我想你明白了。
猜你喜欢
  • 2013-11-15
  • 1970-01-01
  • 2020-12-28
  • 2012-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
相关资源
最近更新 更多