如何获得多个类BS4的div

时间:2017-10-08 11:08:25

标签: html beautifulsoup

如果有多个类,使用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而且它不存在。我怎样才能找到所有评论?

1 个答案:

答案 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可能在这里起着至关重要的作用。