如何使用循环抓取网页的CSS行内容,并分离出内容

时间:2018-07-29 07:31:17

标签: web-scraping beautifulsoup

我正在尝试抓取以下网页,但遇到了一些我无法解决的问题。作为抓鱼的人,我没有深入研究漂亮的汤或html,css。我只是在浏览一些教程,但是它们显示的示例不够深入,无法涵盖实际问题。

因此,这是页面:https://www.fourfourtwo.com/statszone/22-2016/matches/861695/team-stats/6339/0_SHOT_01#tabs-wrapper-anchor

我要做的是提取网页的css行的x1,x2,y1,y2坐标值,并将它们保存在数据集中的相应列x1,x2,y1,y2中。

enter image description here

这些元素对应于网页上的箭头。 enter image description here

我尝试使用查找ID提取整个容器:

import requests
from bs4 import BeautifulSoup
import re

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

soup = BeautifulSoup(page.content, "html.parser")

match_view = soup.find(id="match-view-container")
pitch_obj = match_view.find_all('line', class_="pitch-object")
# to print out the first pitch_object
print(pitch_obj[0])
print(type(pitch_obj[0]))
print(pitch_obj[1])
info = [print(pitch_obj[i]) for i in pitch_obj]
print(info)

问题是,css中的这些不同行具有不同的类名称,例如pitch-object timer-1-24和pitch-object timer-1-26。我只知道从上面的代码中获得以下结果,但不知道如何提取x1,x2,y1和y2。

<line class="pitch-object timer-1-24" marker-end="url(#bigyellow)" marker-start="url(#bigyellowend)" style="stroke:yellow;stroke-width:3" x1="393.52" x2="373.76" y1="234.79" y2="157.941"></line>
<class 'bs4.element.Tag'>
<line class="pitch-object timer-1-26" marker-end="url(#bigblue)" marker-start="url(#bigblueend)" style="stroke:blue;stroke-width:3" x1="283.28" x2="338.4" y1="193.97" y2="164.14"></line>

此外,我无法遍历pitch_obj来从不同行中提取信息。

TypeError: list indices must be integers or slices, not Tag

是否有更好的方法从此网页中的所有CSS线元素中提取x1,x2,y1和y2并将其放入数据集中的单独列中?非常感谢!

1 个答案:

答案 0 :(得分:2)

您可以使用zip()和BeautifulSoup的CSS选择器来组合您要查找的标签(例如svg.select('[x1]')将找到所有具有x1属性的标签)

from bs4 import BeautifulSoup
import requests

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

svg = soup.select_one('svg#pitch')

info = []
for x1, y1, x2, y2 in zip(svg.select('[x1]'), svg.select('[y1]'), svg.select('[x2]'), svg.select('[y2]')):
    info.append((x1['x1'], y1['y1'], x2['x2'], y2['y2']))

for i, (x1, y1, x2, y2) in enumerate(info):
    print("line={}:\tx1={} y1={} x2={} y2={}".format(i+1, x1, y1, x2, y2))

这将为SVG中找到的每一行打印坐标:

line=1: x1=393.52 y1=234.79 x2=373.76 y2=157.941
line=2: x1=283.28 y1=193.97 x2=338.4 y2=164.14
line=3: x1=250 y1=476.57 x2=267.68 y2=435.75
line=4: x1=176.16 y1=283.46 x2=190.72 y2=270.9
line=5: x1=358.16 y1=277.18 x2=417.44 y2=133.469
line=6: x1=238.56 y1=299.16 x2=312.4 y2=258.34
line=7: x1=252.08 y1=291.31 x2=340.48 y2=192.4