2017-08-12 60 views
1

我是編程新手,所以很有可能我想做我想做的事完全不是這樣做的。Python刮表

我試圖從這個網站上刮排積分榜 - http://www.flashscore.com/hockey/finland/liiga/ - 現在如果我甚至可以用團隊名稱刮一列,那也沒關係,所以我嘗試找到類爲「participant_name col_participant_name col_name」的td標籤,但代碼返回空括號:

import requests 
from bs4 import BeautifulSoup 
import lxml 

def table(url): 
    teams = [] 
    source = requests.get(url).content 
    soup = BeautifulSoup(source, "lxml") 
    for td in soup.find_all("td"): 
     team = td.find_all("participant_name col_participant_name col_name") 
     teams.append(team) 
     print(teams) 

table("http://www.flashscore.com/hockey/finland/liiga/") 

我試過用tr標籤來檢索整行,但沒有成功。

回答

2

我覺得這裏的主要問題是,您要湊使用requests一個動態生成的內容,注意有沒有participant_name col_participant_name col_name文本在所有頁面的HTML源代碼,這意味着這是由使用JavaScript生成網站。對於工作,你應該ChromeDriver或者你找到更好的驅動程序一起使用類似selenium,下面是同時使用的提到的工具的例子:

from bs4 import BeautifulSoup 
from selenium import webdriver 

url = "http://www.flashscore.com/hockey/finland/liiga/" 

driver = webdriver.Chrome() 
driver.get(url) 

source = driver.page_source 

soup = BeautifulSoup(source, "lxml") 
elements = soup.findAll('td', {'class':"participant_name col_participant_name col_name"}) 

我覺得你的代碼的另一個問題是你的方式試圖訪問標籤,如果你想匹配一個特定的class或任何其他特定的屬性,你可以使用Python的字典作爲參數.findAll函數。

現在我們可以使用elements找到所有球隊的名字,試圖print(elements[0])並注意球隊的名字是a標籤中,我們可以使用.a.text訪問它,所以是這樣的:

teams = [] 
for item in elements: 
    team = item.a.text 
    print(team) 
    teams.append(team) 

print(teams) 

teams現在應該是所需的輸出:

>>> teams 
['Assat', 'Hameenlinna', 'IFK Helsinki', 'Ilves', 'Jyvaskyla', 'KalPa', 'Lukko', 'Pelicans', 'SaiPa', 'Tappara', 'TPS Turku', 'Karpat', 'KooKoo', 'Vaasan Sport', 'Jukurit'] 

teams也可以使用創建列表理解

teams = [item.a.text for item in elements] 
+0

我很高興提供幫助!請記住[接受](https://meta.stackexchange.com/a/5235)答案,如果有幫助的話,這對社區是一個總體的好處。 –

+0

真棒 - 謝謝。 我試圖使它現在基於行工作,但行沒有共同的單個類,但每個人都有獨特的類,而不是像這樣: 奇怪的glib-participant-I9wm5xTA, 即使是glib參與者-zV5a4drH 依此類推。有沒有辦法讓下面的代碼在名稱中查找具有特定字符串的類(在這種情況下,它將是「glib-participant」)而不是全名? rows = soup.findAll('tr',{'class':「participant_name col_participant_name col_name」}) –

+0

@SomeGuy我想你可以使用'regex'表達式。 'soup.findAll('tr',{'class':re.compile(「你的正則表達式」)})' –

1

你非常接近。

從一開始就不那麼有抱負,只關注「participant_name」。看看https://www.crummy.com/software/BeautifulSoup/bs4/doc/#find-all。我想你想要的東西是這樣的:

for td in soup.find_all("td", "participant_name"): 

此外,你必須看到不同的網頁內容比我。在URL的wget之後,grep在文本中根本找不到「participant_name」。您需要驗證您的代碼是否正在查找ID文本或HTML文本中實際存在的類。

2

先生Aguiar打我吧!我只想指出,你可以單獨使用硒來完成。當然,他指出這是動態加載其大部分內容的衆多網站之一。

您可能有興趣觀察我已經使用了xpath表達式。這些通常使你能夠以緊湊的方式說出你想要的東西。一旦習慣了它們,閱讀並不難。

>>> from selenium import webdriver 
>>> driver = webdriver.Chrome() 
>>> driver.get('http://www.flashscore.com/hockey/finland/liiga/') 
>>> items = driver.find_elements_by_xpath('.//span[@class="team_name_span"]/a[text()]') 
>>> for item in items: 
...  item.text 
... 
'Assat' 
'Hameenlinna' 
'IFK Helsinki' 
'Ilves' 
'Jyvaskyla' 
'KalPa' 
'Lukko' 
'Pelicans' 
'SaiPa' 
'Tappara' 
'TPS Turku' 
'Karpat' 
'KooKoo' 
'Vaasan Sport' 
'Jukurit' 
+0

很好有一個基於'selenium'的解決方案,*包括*電池*解決方案! –

+1

@ViníciusAguiar:非常感謝。我很高興看到你的答案被接受。 –

1

達到相同的使用CSS選擇器可以讓你使代碼更易讀和簡潔:

from selenium import webdriver; driver = webdriver.Chrome() 

driver.get('http://www.flashscore.com/hockey/finland/liiga/') 
for player_name in driver.find_elements_by_css_selector('.participant_name'): 
    print(player_name.text) 
driver.quit()