无法处理网页中一些复杂的布局内容
Posted
技术标签:
【中文标题】无法处理网页中一些复杂的布局内容【英文标题】:Can't deal with some complicated laid-out content from a webpage 【发布时间】:2019-01-13 07:12:19 【问题描述】:我用 Python 结合 BeautifulSoup 编写了一个脚本来解析网页中的一些内容。在登录页面中有两个表格。我需要使用第一个表中的Results
选项卡,这将导致目标页面。
从目标页面我只关注此信息Grade: M 300 metres
等等。在其上方有多个选项卡,例如1,2,3,4
等,它们具有不同的Grade
状态。我想把它们都拿回来。
由于登陆页面中的Results
选项卡没有任何链接,我不得不使用post
请求从目标页面获取内容。在这种情况下,浏览器模拟器不适合我。
底线是我需要使用六个post
请求才能到达六个Results
选项卡的内容。
我在下面粘贴的脚本可以处理最后一个results
选项卡的内容。如何修复循环以同时从所有 Results
选项卡获取内容?
这是我的尝试:
import requests
from bs4 import BeautifulSoup
url = "https://www.thedogs.com.au/Racing/Results.aspx?SearchDate=3-Jun-2018"
def get_info(session,link):
session.headers['User-Agent'] = "Mozilla/5.0"
res = session.get(link)
soup = BeautifulSoup(res.text,"lxml")
formdata =
for items in soup.select("#aspnetForm input"):
if "ctl00$ContentPlaceHolder1$rptrLatestRacingResults$ctl" in items.get("name"):continue
if "ctl00$ContentPlaceHolder1$rptrSearchResults$ctl0" in items.get("name"):
formdata[items.get("name")] = items.get("value")
else:
formdata[items.get("name")] = items.get("value")
session.headers['User-Agent'] = "Mozilla/5.0"
req = session.post(link,data = formdata)
soup = BeautifulSoup(req.text,"lxml")
for iteminfo in soup.select("[id^='ctl00_ContentPlaceHolder1_tabContainerRaces_tabRace'] span"):
if "Grade:" in iteminfo.text:
print(iteminfo.text)
if __name__ == '__main__':
with requests.Session() as session:
get_info(session,url)
查看下面的两张图片(一张接一张)以识别我要获取的内容:
【问题讨论】:
你在这里的经历让我很感兴趣。看到 cmets 已被删除,我的兴趣被进一步激发。我已经打开了一个关于 meta 的问题来讨论这个问题:meta.***.com/questions/372078/… 【参考方案1】:您可以利用 CSS 选择器 span[id$=lblResultsRaceName]
,它会查找所有 id 以 lblResultsRaceName 和 'td > span'
结尾的 span,它会查找所有具有直接父级 <td>
的 span:
此代码 sn-p 将检查所有比赛结果并打印所有比赛:
import requests
from bs4 import BeautifulSoup
url = "https://www.thedogs.com.au/Racing/Results.aspx?SearchDate=3-Jun-2018"
def get_info(session,link):
session.headers['User-Agent'] = "Mozilla/5.0"
res = session.get(link)
soup = BeautifulSoup(res.text,"lxml")
formdata = i['name']: i['value'] for i in soup.select('input[type=hidden]')
for race_name, i in zip(soup.select('span[id$=lblResultsRaceName]'), soup.select('input[id$=btnViewResults]')):
print(race_name.text.strip())
formdata[i['name']] = 'Results'
req = session.post(link,data = formdata)
soup = BeautifulSoup(req.text,"lxml")
for panel in soup.select('div[id^=ctl00_ContentPlaceHolder1_tabContainerRaces_tabRace]'):
print(panel.select('td > span')[0].text.strip(), panel.select('td > span')[1].text.strip())
print('#' * 80)
if __name__ == '__main__':
with requests.Session() as session:
get_info(session,url)
打印:
Healsville
Race 1 Grade: M 300 metres
Race 2 Grade: M 350 metres
Race 3 Grade: 6/7 350 metres
Race 4 Grade: R/W 300 metres
Race 5 Grade: 5 350 metres
Race 6 Grade: SE 350 metres
Race 7 Grade: 4/5 350 metres
Race 8 Grade: SE 350 metres
Race 9 Grade: 7 300 metres
Race 10 Grade: 6/7 300 metres
Race 11 Grade: 4/5 300 metres
Race 12 Grade: 5 300 metres
################################################################################
Sale
Race 1 Grade: M 440 metres
Race 2 Grade: M 440 metres
Race 3 Grade: R/W 520 metres
Race 4 Grade: 7 440 metres
Race 5 Grade: R/W 440 metres
Race 6 Grade: 4/5 520 metres
Race 7 Grade: R/W 440 metres
Race 8 Grade: 4/5 440 metres
Race 9 Grade: 6/7 440 metres
Race 10 Grade: R/W 440 metres
Race 11 Grade: R/W 440 metres
Race 12 Grade: 5 520 metres
################################################################################
...and so on.
【讨论】:
它完美地做到了@Andrej。提供了一个加号。过段时间会接受的。顺便说一句,您能否简要介绍一下formdata[i['name']] = 'Results'
这一行实际上在这里做什么?谢谢。
@asmitu 使用formdata[i['name']] = 'Results'
我选择要查看的比赛结果。我通过Firefox中的源代码查看了它,这是type="submit"
表单输入变量。
抱歉 Andrej 再次打扰您。 formdata[i['name']] = 'Results'
对我来说似乎有点高级,我无法解开这个谜题。当它在for loop
之前使用时,它在字典中收集了一些names
和values
。但是,当您尝试使用formdata[i['name']] = 'Results'
时,它不会只抓住单词Results
将其先前存储在字典中的内容踢出。再次感谢您提供任何见解。
@asmitu 我知道,旧的“结果”将保留在 formdata
中,但服务器将只处理添加的最后一个 - 这是此特定服务器的工作方式。以上是关于无法处理网页中一些复杂的布局内容的主要内容,如果未能解决你的问题,请参考以下文章