2017-08-07 182 views
0

我使用維基百科API獲取信息框數據。我想從這個信息框數據解析website url。我嘗試使用mwparserfromhell解析網站網址,但不同的關鍵字有不同的格式。從維基百科解析網站信息框數據

這裏有幾個模式的網站 -

url     = <!-- {{URL|www.example.com}} --> 
| url = [https://www.TheGuardian.com/ TheGuardian.com] 
| url = <span class="plainlinks">[https://www.naver.com/ www.naver.com]</span> 
|url    = [https://www.tmall.com/ tmall.com] 
|url   = [http://www.ustream.tv/ ustream.tv] 

我需要在解析official website link由維基百科所支持的所有模式的幫助?

編輯 -

碼 -

# get infobox data 
import requests 
# keyword 
keyword = 'stackoverflow.com' 
# wikipedia api url 
api_url = (
    'https://en.wikipedia.org/w/api.php?action=query&prop=revisions&' 
    'rvprop=content&titles=%s&rvsection=0&format=json' % keyword) 
# api request 
resp = requests.get(api_url).json() 
page_one = next(iter(resp['query']['pages'].values())) 
revisions = page_one.get('revisions', []) 
# infobox daa 
infobox_data = next(iter(revisions[0].values())) 

# parse website url 
import mwparserfromhell 
wikicode = mwparserfromhell.parse(infobox_data) 
templates = wikicode.filter_templates() 
website_url_1 = '' 
website_url_2 = '' 
for template in templates: 
    # Pattern - `URL|http://x.com` 
    if template.name == "URL": 
     website_url_1 = str(template.get(1).value) 
     break 
    if not website_url_1: 
     # Pattern - `website = http://x.com` 
     try: 
      website_url_2 = str(template.get("website").value) 
     except ValueError: 
      pass 
    if not website_url_1: 
     # Pattern - `homepage = http://x.com` 
     try: 
      website_url_2 = str(template.get("homepage").value) 
     except ValueError: 
      pass 
if website_url_1: 
    website_url = website_url_1 
elif website_url_2: 
    website_url = website_url_2 
+0

你能告訴你的代碼? mwparserfromhell應該能夠處理所有這些(除了第一個不會實際顯示鏈接的)。 – Tgr

+0

@Tgr添加了我正在使用的代碼。它只涵蓋少數情況。 –

回答

0

一個可以分析你已經使用正則表達式和BeautifulSoup提到的模式。可以想象,可以通過擴展這種方法來解析附加模式。

我從行的開頭刪除包含'url ='的內容,然後使用BeautifulSoup處理餘數。由於BeautifulSoup封裝了它形成完整頁面的內容,原始內容可以作爲body元素的文本獲得。

>>> import re 
>>> patterns = '''\ 
... url     = <!-- {{URL|www.example.com}} --> 
... | url = [https://www.TheGuardian.com/ TheGuardian.com] 
... | url = <span class="plainlinks">[https://www.naver.com/ www.naver.com]</span> 
... |url    = [https://www.tmall.com/ tmall.com] 
... |url   = [http://www.ustream.tv/ ustream.tv]''' 
>>> import bs4 
>>> regex = re.compile(r'\s*\|?\s*url\s*=\s*', re.I) 
>>> for pattern in patterns.split('\n'): 
...  soup = bs4.BeautifulSoup(re.sub(regex, '', pattern), 'lxml') 
...  if str(soup).startswith('<!--'): 
...   'just a comment' 
...  else: 
...   soup.find('body').getText() 
... 
'just a comment' 
'[https://www.TheGuardian.com/ TheGuardian.com]' 
'[https://www.naver.com/ www.naver.com]' 
'[https://www.tmall.com/ tmall.com]' 
'[http://www.ustream.tv/ ustream.tv]' 
+0

謝謝,如果有人能夠提供一個全面的模式列表,這可能很有用。我檢查了幾百頁的數據,但沒有找到任何標準模式集。 –

+0

我需要更具體的解決方案來解析來自wikipedia API數據的'website'。這些線上的任何內容都會有所幫助。 –

+0

我認爲你已經完成了對其他人知道這一點的研究。沒有標準模式或全面模式。儘管如此,你仍然可以通過有用的方式來擴展它。 –

0

mwparserfromhell是一個很好的工具:

import mwclient 
import mwparserfromhell 

site = mwclient.Site('en.wikipedia.org') 
text = site.pages[pagename].text() 
wikicode = mwparserfromhell.parse(text) 
templates = wikicode.filter_templates(matches='infobox .*') 
url = templates[0].get('url').value 

url_template = url.filter_templates(matches='url') 
url_link = url.filter_external_links() 
if url_template: 
    print url_template[0].get(1) 
elif url_link: 
    print url_link.url 
else: 
    print url 
+0

此代碼-'url = templates [0] .get('url').value'在所有情況下都不起作用。例如。 https://en.wikipedia.org/wiki/National_Institute_of_Technology,_Karnataka 數據中的url沒有標準屬性。我從我的觀察中發現了「網站,網址和主頁」。你知道所有有效的屬性名稱嗎? –

+1

不可以。您可能會有更多的運氣問維基百科上的這類問題(例如[技術村泵](https://en.wikipedia.org/wiki/Wikipedia:Village_pump_(technical))。 – Tgr