我试图抓取https://www.betexplorer.com/soccer/england/premier-league/fixtures/来提取'a'标签中包含的文本,特别是在带有类“table-main”的表中,然后是其中的每一行。第一个td包含带有两个团队名称的文本,带有td类,“h-text-left”。不确定问题是否与我的循环有关,但我得到的错误消息似乎我在循环中的最后一行错误地使用bs4。
我可以用表格“table-main”抓住表格中的每个tr,然后每个td用类“h-text-left”。我试图单独提取'a'元素,甚至不是'a'文本时,我正在打一个deadend。
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()?
>>>
您可以使用单个类将其减少到更快的选择器方法。所有链接都具有相同的类名,因此您可以将其传递给列表解析中的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)
您应该使用内置功能来查找嵌套结构。您可以使用.css
指定'.class_name'
类,并使用''first selector'>'second selector'(或更多选择器)查找嵌套结构。这一起看起来像:
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')
将选择a
元素内的所有td
元素,这些元素位于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)
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_all()
# ERROR
soup.find_all(...).find_all(...)
# ERROR
soup.find_all(...).find(...)