如果有多个类,使用BeautifulSoup4获取div的最有效方法是什么?
我有一个像这样的html结构:
<div class='class1 class2 class3 class4'>
<div class='class5 class6 class7'>
<div class='comment class14 class15'>
<div class='date class20 showdate'> 1/10/2017</div>
<p>comment2</p>
</div>
<div class='comment class25 class9'>
<div class='date class20 showdate'> 7/10/2017</div>
<p>comment1</p>
</div>
</div>
</div>
我想通过评论获得div。通常嵌套类没有问题,但我不知道命令的原因:
html = BeautifulSoup(content, "html.parser")
comments = html.find_all("div", {"class":"comment"})
不起作用。它给出了空数组。 我想这是因为有很多类,所以他只用注释类来查找div而且它不存在。我怎样才能找到所有评论?
答案 0 :(得分:1)
显然,提取评论部分的URL与检索主要内容的原始URL不同。
这是您提供的原始网址:
http://community.sparknotes.com/2017/10/06/find-out-your-colleges-secret-mantra-we-hack-college-life-at-the-100-of-the-best
在幕后,如果您在Chrome开发者菜单的网络标签中记录网络日志,您将看到浏览器发送的所有网址列表。其中大多数是用于获取图像和脚本。很少涉及其他网站,如Facebook或谷歌(用于分析等)。浏览器向该特定站点发送另一个请求(sparknotes),它为您提供了注释部分。这是URL:
http://community.sparknotes.com/commentlist?post_id=1375724&page=1&comment_type=&_=1507467541548
post_id
的值可以在我们请求第一个网址时返回的网页中找到。它包含在input
标记中,该标记具有隐藏属性。
<input type="hidden" id="postid" name="postid" value="1375724">
您可以使用简单的soup.find('input', {'id': 'postid'})['value']
从第一个网页中提取此信息。当然,由于这会唯一地标识帖子,因此您无需担心其在每个请求上动态更改。
我无法在主页的任何位置找到传递给'_'参数(网址的最后一个参数)的'1507467541548'值,也不会找到任何网页的响应标头设置的Cookie中的任何位置。
然而,我出去试图通过传递没有'_'参数的URL来获取URL,并且它有效。
所以,这是适合我的整个脚本:
from bs4 import BeautifulSoup
import requests
req_headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'en-US,en;q=0.8',
'Connection': 'keep-alive',
'Host': 'community.sparknotes.com',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
}
with requests.Session() as s:
url = 'http://community.sparknotes.com/2017/10/06/find-out-your-colleges-secret-mantra-we-hack-college-life-at-the-100-of-the-best'
r = s.get(url, headers=req_headers)
soup = BeautifulSoup(r.content, 'lxml')
post_id = soup.find('input', {'id': 'postid'})['value']
# url = 'http://community.sparknotes.com/commentlist?post_id=1375724&page=1&comment_type=&_=1507467541548' # the original URL found in network tab
url = 'http://community.sparknotes.com/commentlist?post_id={}&page=1&comment_type='.format(post_id) # modified by removing the '_' parameter
r = s.get(url)
soup = BeautifulSoup(r.content, 'lxml')
comments = soup.findAll('div', {'class': 'commentCite'})
for comment in comments:
c_name = comment.div.a.text.strip()
c_date_text = comment.find('div', {'class': 'commentBodyInner'}).text.strip()
print(c_name, c_date_text)
如您所见,我没有使用第二个requests.get
的标头。所以我不确定它是否是必需的。您也可以在第一个请求中尝试省略它们。但请确保您使用requests
,因为我没有尝试使用urllib
。 Cookies可能在这里起着至关重要的作用。