簡體   English   中英

嘗試使用 python 和 bs4 從特定的“td”中抓取所有“a”文本

[英]Trying to scrape all 'a' text from within specific 'td's using python and bs4

我正在嘗試抓取https://www.betexplorer.com/soccer/england/premier-league/fixtures/以提取包含在 'a' 標簽中的文本,特別是在帶有類“table-main”的表中,然后對於其中的每一行。 第一個 td 包含帶有兩個團隊名稱的文本,帶有一個 td 類“h-text-left”。 不確定問題是否與我的循環有關,但我收到的錯誤消息似乎是我在循環的最后一行錯誤地使用了 bs4。

我可以用類“table-main”抓取表中的每個 tr,然后再用類“h-text-left”抓取每個 td。 我在嘗試單獨提取“a”元素時遇到了死胡同,甚至不提取“a”文本。

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent':
           'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'}

r = requests.get('https://www.betexplorer.com/soccer/england/premier-league/fixtures/', headers=headers)

c = r.content

soup = BeautifulSoup(c)

fixture_table = soup.find('table', attrs = {'class': 'table-main'})

for tr in soup.find_all('tr'):
    match_tds = tr.find_all('td', attrs = {'class': 'h-text-left'})
    matches = match_tds.find_all('a')

當我嘗試查找所有“a”標簽時的最后一行會引發以下錯誤:

...     matches = match_tds.find_all('a')
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
  File "C:\Users\Glypt\AppData\Local\Programs\Python\Python36-32\lib\site-packages\bs4\element.py", line 1884, in __getattr__
    "ResultSet object has no attribute '%s'. You're probably treating a list of items like a single item. Did you call find_all() when you meant to call find()?" % key
AttributeError: ResultSet object has no attribute 'find_all'. You're probably treating a list of items like a single item. Did you call find_all() when you meant to call find()?
>>>

match_tds是一個列表,而不是單個元素 - 您可以通過tr.find_all(...)獲得它 - 所以您必須使用for循環來運行另一個find_all()

for tr in soup.find_all('tr'):
    match_tds = tr.find_all('td', attrs = {'class': 'h-text-left'})
    for item in match_tds:
        matches = item.find_all('a')
        for a in matches:
            print(a['href'])

如果您使用find()來獲取第一個元素,那么您可以與另一個find()find_all()

soup.find(...).find(...).find_all(...)

但是你不能find() find_all()之后使用find()find_all()

# ERROR
soup.find_all(...).find_all(...) 

# ERROR
soup.find_all(...).find(...) 

您應該使用內置功能來查找嵌套結構。 您可以使用'.class_name'指定.css類,並使用“第一個選擇器”>“第二個選擇器”(甚至更多選擇器)查找嵌套結構。 這將看起來像:

import requests
from bs4 import BeautifulSoup

s = requests.session()
s.headers['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'
res = s.get('https://www.betexplorer.com/soccer/england/premier-league/fixtures/')
soup = BeautifulSoup(res.text, 'html.parser')

matches = soup.select('.table-main  tr  td  a')
for match in matches:
    print(match.getText())

matches = soup.select('.table-main tr td a')將選擇所有在td元素中的a元素,這些元素在tr元素中,並且在class=table-main元素中。 此外,您可以使用matches = soup.select('td > a')>運算符)來指定a元素直接位於td元素內。 我想這可能會大大簡化您的代碼!

注意我無法在我的機器上測試這個,因為無法確認 SSL 證書並引發requests.exceptions.SSLError

要獲取文本,請嘗試:

for td in soup.findAll('td', attrs = {'class': 'h-text-left'}):
    print(td.findAll('a')[0].text)

您可以使用單個類將其簡化為更快的選擇器方法。 所有鏈接都具有相同的類名,因此您可以將其傳遞給select ,在列表理解中,為您提供所有鏈接。

import requests
from bs4 import BeautifulSoup
r = requests.get('https://www.betexplorer.com/soccer/england/premier-league/fixtures/')
soup = BeautifulSoup(r.content, 'lxml')
matches = [item['href'] for item in soup.select('.in-match')]

賠率

import requests
from bs4 import BeautifulSoup
r = requests.get('https://www.betexplorer.com/soccer/england/premier-league/fixtures/')
soup = BeautifulSoup(r.content, 'lxml')
odds = [item['data-odd'] for item in soup.select('.table-main__odds [data-odd]')]
print(odds)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM