我试图使用python3和beautifulsoup4从在线学校列表中提取数据。以下是数据变量的定义方式:
soup = BeautifulSoup(r.content, "html.parser")
g_data = soup.find_all("div", {"class": "school_data"})
以下是g_data []中每个列表元素的结构:
<div class="school_data">
<h4 class="cyan_header">Coop Tech<br/></h4>
<dl>
<dt>School Type: </dt>
<dd>Academic</dd>
<dt>Another Heading: </dt>
<dd>etc.</dd>
</dl>
</div>
在开始试图拔出田地时,我开始说:
for item in g_data:
try:
print(item.contents[0].find_all("h4",{"class": "school_data"})[0].text)
except:
pass
try:
schoolType = item.contents[1].find("dt", text="School Type: ")
print(schoolType.find_next_sibling("dd").text)
except:
pass
对于学校名称(h4标签),我希望上面打印第一个h4标签中的文本&#34;内容&#34;但它没有返回任何东西。我做了最终让它从h4标签打印文本只是通过这样做:
print(item.contents[0].text)
这有局限性......为什么没有原作?
对于schoolType部分(循环中的第二次尝试),我得到一个&#34; TypeError:find()不接受关键字参数&#34;。我读了一下,但看到别人推荐这个,我不确定为什么会出错。我怀疑我也做错其他的东西......例如,当我尝试简单地打印出item.contents [1]进行调试时,我得到了一堆空行。
有任何帮助吗?接下来,我将为数据创建变量并将其写入csv。 python和stackoverflow的新手,谢谢。
答案 0 :(得分:0)
如果您希望 dl 标记内的子项中的所有文本都是前一个 h4 cyan_header 的兄弟,那么您只需从dls中提取子标记:< / p>
h = """<div class="school_data">
<h4 class="cyan_header">Coop Tech<br/></h4>
<dl>
<dt>School Type: </dt>
<dd>Academic</dd>
<dt>Another Heading: </dt>
<dd>etc.</dd>
</dl>
</div>"""
from bs4 import BeautifulSoup, Tag
soup = BeautifulSoup(h)
h4s = soup.select("div.school_data h4.cyan_header")
for h4 in h4s:
print([child.text for child in h4.find_next("dl").children if isinstance(child, Tag)] )
哪会给你:
[u'School Type: ', u'Academic', u'Another Heading: ', u'etc.']
为什么获得find() takes no keyword arguments"
是因为item.contents[1]
是字符串而不是标记,因此您实际上是在调用str.find
。
此外,如果您只想要返回一个标记,则应使用 find 而非 find_all ,find会给您一个匹配,第一个匹配。
您还可以使用dl标记提取所有dd标签和dt标签:
h4s = soup.select("div.school_data h4.cyan_header")
for h4 in h4s:
dl = h4.find_next("dl")
dds = dl.find_all("dd")
dts = dl.find_all("dt")
print(dds)
print(dts)
哪会给你:
[<dd>Academic</dd>, <dd>etc.</dd>]
[<dt>School Type: </dt>, <dt>Another Heading: </dt>]
你使用什么完全取决于你想要什么以及html的其余部分是如何构建的,另外你应该做的另一件事是使用空白,除非至少打印/记录任何错误。