BeautifulSoup 循环没有遍历其他节点

Posted

技术标签:

【中文标题】BeautifulSoup 循环没有遍历其他节点【英文标题】:BeautifulSoup loop isn't iterating through other nodes 【发布时间】:2019-06-02 21:16:18 【问题描述】:

在这方面有非常相似的场景;但我一直在和别人比较。 Getting from Clustered Nodes 等等。但不知何故;我不确定为什么我的for loop 没有迭代并从其他元素中获取文本,而只是从节点的第一个元素中获取。

from requests import get
from bs4 import BeautifulSoup

url = 'https://shopee.com.my/'
l = []

headers = 'User-Agent': 'Googlebot/2.1 (+http://www.google.com/bot.html)'

response = get(url, headers=headers)
html_soup = BeautifulSoup(response.text, 'html.parser')


def findDiv():
     try:
        for container in html_soup.find_all('div', 'class': 'section-trending-search-list'):
            topic = container.select_one(
                'div._1waRmo')
            if topic:
                print(1)
                d = 
                    'Titles': topic.text.replace("\n", "")
                print(2)
                l.append(d)
        return d
    except:
        d = None

findDiv()
print(l)

【问题讨论】:

这行不应该是:topic = container.select_one('._1waRmo') - 换句话说,只是类名。 html_soup.find_all('div', 'class': 'section-trending-search-list') 行也只会找到根元素,你不需要 html_soup.find_all('div') 来枚举所有 div。或者如果你想枚举 div 类 _25qBG5 下的所有内容,然后找到它(称它为 toplevel,然后 options = toplevel.find('div') 然后 for option in options。 【参考方案1】:
from requests import get
from bs4 import BeautifulSoup

url = 'https://shopee.com.my/'
l = []

headers = 'User-Agent': 'Googlebot/2.1 (+http://www.google.com/bot.html)'

response = get(url, headers=headers)
html_soup = BeautifulSoup(response.text, 'html.parser')


def findDiv():
     try:
        for container in html_soup.find_all('div', 'class': '_25qBG5'):
            topic = container.select_one('div._1waRmo')
            if topic:
                d = 'Titles': topic.text.replace("\n", "")
                l.append(d)
        return d
     except:
        d = None

findDiv()
print(l)

输出:

['Titles': 'school backpack', 'Titles': 'oppo case', 'Titles': 'baby chair', 'Titles': 'car holder', 'Titles': 'sling beg']

我再次建议您使用selenium。如果您再次运行此程序,您将看到您将在列表中获得一组不同的 5 个字典。每次您提出请求时,他们都会提供 5 个随机趋势项目。但他们确实有一个“更改”按钮。如果您使用 selenium,您可能只需单击它并继续抓取所有热门项目。

【讨论】:

我在标题上的错误,因为我忘记重新编辑标题以包含'User-Agent': 'Googlebot/2.1 (+http://www.google.com/bot.html) @Minial 我将删除我的答案。并提出正确的解决方案。 感谢您的推荐,我可能会在 Selenium 上找到更多信息,因为我相信它会帮助我在未来顺利完成很多事情。【参考方案2】:

试试这个: 顶层是找到选项的根,然后我们找到它下面的所有 div。 我希望这是你想要的。

from requests import get
from bs4 import BeautifulSoup

url = 'https://shopee.com.my/'
l = []

headers = 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0'

response = get(url, headers=headers)
html_soup = BeautifulSoup(response.text, 'html.parser')


def findDiv():
    try:
        toplevel = html_soup.find('._25qBG5')
        for container in toplevel.find_all('div'):
            topic = container.select_one('._1waRmo')
            if topic:
                print(1)
                d = 'Titles': topic.text.replace("\n", "")
                print(2)
                l.append(d)
                return d
    except:
        d = None

findDiv()
print(l)

这可以很好地使用本地文件进行枚举。当我尝试使用给定的 url 时,网站没有返回您显示的 html。

from requests import get
from bs4 import BeautifulSoup

url = 'path_in_here\\test.html'
l = []

headers = 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0'

example = open(url,"r")
text = example.read()

#response = get(url, headers=headers)
#html_soup = BeautifulSoup(response.text, 'html.parser')
html_soup = BeautifulSoup(text, 'html.parser')

print (text)

def findDiv():
    #try:
        print("finding toplevel")
        toplevel = html_soup.find("div",  "class":  "_25qBG5" )
        print ("found toplevel")
        divs = toplevel.findChildren("div", recursive=True)
        print("found divs")

        for container in divs:
            print ("loop")
            topic = container.select_one('.1waRmo')
            if topic:
                print(1)
                d = 'Titles': topic.text.replace("\n", "")
                print(2)
                l.append(d)
                return d
    #except:
    #    d = None
    #    print ("error")

findDiv()
print(l)

【讨论】:

toplevel = html_soup.find('._25qBG5') 遗憾地返回一个空值。这是我正在寻找的,我理解这个概念;但不知何故,当我要求它时,它会返回None

以上是关于BeautifulSoup 循环没有遍历其他节点的主要内容,如果未能解决你的问题,请参考以下文章

深度优先搜索DFS

遍历文档树

BeautifulSoup文档3-详细方法 | 如何对文档树进行遍历?

爬虫库之BeautifulSoup学习

练习字典的循环遍历:实现多层级节点存取

Python爬虫教程-24-数据提取-BeautifulSoup4