如何刮除不属于类中任何属性的元素

时间:2018-07-30 03:24:58

标签: web-scraping beautifulsoup

这个问题发生在我昨天问的同一页面上。网址是: https://www.fourfourtwo.com/statszone/22-2016/matches/861695/team-stats/6339/0_SHOT_01#tabs-wrapper-anchor

我正在尝试刮擦比赛日期: 我想得到:

法兰克福瓦尔德体育场(Waldstadion Frankfurt),2017年5月20日,星期六-14:30

然后,提取:

2017年5月20日

enter image description here

而这恰好是来自inspect元素视图的地方: enter image description here

我尝试在以下代码中访问此div标签和team类:

import requests
from bs4 import BeautifulSoup
import csv
import re

url = "https://www.fourfourtwo.com/statszone/22-2016/matches/861695/team-stats/6339/0_SHOT_01#tabs-wrapper-anchor"
response = requests.get(url)
soup = BeautifulSoup(response.text, "lxml")
# Try find date
date = soup.select('div.teams')
date_raw = date[0].text
date_strip = date_raw.strip()
y = re.findall('(^[A-Z].+)\n', date_strip)
y1 = str(y).strip()
print(y1)

但这并不是很成功...结果仍然以某种方式存在于列表中,并且有很多空间需要修剪。问题是这个班级有很多孩子,我只想访问class ='teams'文本元素并提取日期。

['Waldstadion Frankfurt, Saturday, May 20, 2017 - 14:30      ']

有没有更好的方法来提取此元素?非常感谢您的帮助和时间。

3 个答案:

答案 0 :(得分:1)

您可以在解析之前使用普通的JS。

document.getElementById("match-head").
    children[0].
    innerText. 
    split(/[,-]/).
    splice(1,2).
    join("")

// produces " Saturday May 20"

前三个语句只是W3C DOM;最后三个是数组操作,以提取由“-”或“,”字符分隔的第二和第三项,并将它们重新结合在一起。

答案 1 :(得分:1)

如您所见,所需文本是<div class="teams">之后的第一内容。您可以在带有.contents属性的BeautifulSoup中访问它,该属性可以被索引(如果是第一个内容,则为0):

from bs4 import BeautifulSoup
import requests

r = requests.get('https://www.fourfourtwo.com/statszone/22-2016/matches/861695/team-stats/6339/0_SHOT_01#tabs-wrapper-anchor')
soup = BeautifulSoup(r.text, 'lxml')

print(soup.select_one('div.teams').contents[0].strip())

打印:

Waldstadion Frankfurt, Saturday, May 20, 2017 - 14:30

编辑:

要解析位置,日期和时间的字符串,可以使用正则表达式:

from bs4 import BeautifulSoup
import requests
import re

r = requests.get('https://www.fourfourtwo.com/statszone/22-2016/matches/861695/team-stats/6339/0_SHOT_01#tabs-wrapper-anchor')
soup = BeautifulSoup(r.text, 'lxml')

data = soup.select_one('div.teams').contents[0].strip()

place, date, time = re.search(r'(.*?)(?:,.*?)((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Dec)\s+\d+,\s+\d+).*?(\d+:\d+)', data).groups()
print(place)
print(date)
print(time)

这将打印:

Waldstadion Frankfurt
May 20, 2017
14:30

此正则表达式的解释为here

答案 2 :(得分:1)

我的第一选择dateutil.parser无法找到日期,因此我使用了一个简单的正则表达式来提取日期。唯一需要注意的是,日期必须以完整的月份名称开头,并以短划线或换行符结尾。

import re
import requests
from bs4 import BeautifulSoup

url = "https://www.fourfourtwo.com/statszone/22-2016/matches/861695/team-stats/6339/0_SHOT_01#tabs-wrapper-anchor"
soup = BeautifulSoup(requests.get(url).text, "lxml")

pattern = "(?:January|February|March|April|May|June|July|August|September|October|November|December)[^-\n.]+"
print(re.search(pattern, soup.select("div.teams")[0].text).group().strip())

输出:

May 20, 2017

我个人认为该网站在日期格式方面比逗号或空格更加一致,但这是这样的版本:

import re
import requests
from bs4 import BeautifulSoup

url = "https://www.fourfourtwo.com/statszone/22-2016/matches/861695/team-stats/6339/0_SHOT_01#tabs-wrapper-anchor"
soup = BeautifulSoup(requests.get(url).text, "lxml")

print(" ".join(re.split("\s+", soup.select("div.teams")[0].text)[4:7]))