V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
omg21
V2EX  ›  Python

用 BS4 如何搜索文本内容,然后再取出其标签?

  •  
  •   omg21 · 2016-10-02 22:29:48 +08:00 · 4091 次点击
    这是一个创建于 2956 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比方说下面这样的代码,

    <p id="a1">新闻</p>
    <p id="a2">娱乐</p>

    我需要搜索“娱乐”,如果找到了,就取出标签“<p id="a2">娱乐</p>”,我试过用 soup.find_all(),但是这个只能搜索标签,不能搜索内容。
    27 条回复    2016-10-03 20:05:27 +08:00
    omg21
        1
    omg21  
    OP
       2016-10-02 22:52:53 +08:00
    我用 soup.find_all(text="娱乐")得到结果是 []
    用 soup.find(text="娱乐")得到结果是 None
    所以现在不知道应该如何才能取到标签
    practicer
        2
    practicer  
       2016-10-02 23:12:46 +08:00
    html = '''<p id="a1">新闻</p>
    <p id="a2">娱乐</p>'''

    bs = BeautifulSoup(html, 'html.parser')
    theTag = bs.find(text='娱乐').find_parent()
    omg21
        3
    omg21  
    OP
       2016-10-02 23:16:45 +08:00
    @practicer 兄弟,这样不行啊,报错。
    gyh
        4
    gyh  
       2016-10-02 23:33:41 +08:00 via iPhone
    对 find_all(p)循环,若 text=="娱乐",赋给一个变量,退出循环。
    这样?
    finalspeed
        5
    finalspeed  
       2016-10-02 23:53:24 +08:00 via Android   ❤️ 1
    Although string is for finding strings, you can combine it with arguments that find tags: Beautiful Soup will find all tags whose .string matches your value for string. This code finds the <a> tags whose .string is “ Elsie ”:

    soup.find_all("a", string="Elsie")
    # [<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>]
    The string argument is new in Beautiful Soup 4.4.0. In earlier versions it was called text:

    soup.find_all("a", text="Elsie")
    # [<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>]
    zqcolor
        6
    zqcolor  
       2016-10-03 07:08:03 +08:00
    soup = bs4.BeautifulSoup(Response)

    a = soup.find('a', text = '下一页')

    url = a['href']
    dsg001
        7
    dsg001  
       2016-10-03 08:15:59 +08:00
    为嘛不用 lxml ?
    //p[text()="娱乐"]
    omg21
        8
    omg21  
    OP
       2016-10-03 08:56:53 +08:00
    @finalspeed 这样可以取到, find_all("a", string="Elsie") ,可是这里面有"a",如果不加"a"能不能取到整条<a>呢?
    在我的实例里,想取<p id="a2">娱乐</p>,这里的标签<p>是变量,也有可能是<div>,<td>,所以只能用 find_all(text="娱乐")这样的方法表述,可是我现在取不出来。
    omg21
        9
    omg21  
    OP
       2016-10-03 08:58:39 +08:00
    @gyh 抱歉提问没说详细,<p>标签 在这里是个变量,也有可能是<div>,<td>,所以你这方法不现实
    aristotll
        10
    aristotll  
       2016-10-03 09:16:13 +08:00
    建议用 css selector 迟早要接触这一块的 学习 BS4 自带函数还不如学习这东西更通用
    popu111
        11
    popu111  
       2016-10-03 09:16:29 +08:00 via Android
    @finalspeed 论看英文文档的重要性_(:з」∠)_中文版还没跟进到 4.4.0
    dsg001
        12
    dsg001  
       2016-10-03 09:21:44 +08:00
    @aristotll css 支持文本选择器吗?
    panyanyany
        13
    panyanyany  
       2016-10-03 09:32:09 +08:00
    楼主可以先直接在 outerHTML 里查找到 “娱乐” 然后上溯到最近的标签啊
    sherlocktheplant
        14
    sherlocktheplant  
       2016-10-03 10:09:11 +08:00
    @omg21

    我没试过 不过应该是这样

    result = soup.find_all(string=u"娱乐")

    得到的应该是一个 NavigatableString 的数组:

    for item in result:
    element = item.parent
    sherlocktheplant
        15
    sherlocktheplant  
       2016-10-03 10:13:42 +08:00
    测试了一下应该是
    result = soup.find_all(string=u"娱乐")
    sherlocktheplant
        16
    sherlocktheplant  
       2016-10-03 10:13:52 +08:00
    测试了一下应该是
    result = soup.find_all(text=u"娱乐")
    sherlocktheplant
        18
    sherlocktheplant  
       2016-10-03 10:17:18 +08:00
    string 和 text 都可以
    shoaly
        19
    shoaly  
       2016-10-03 12:05:03 +08:00
    放弃 soup 吧 ,并不鸡汤, 安利你 pyquery, 语法和 jquery 通用
    omg21
        20
    omg21  
    OP
       2016-10-03 14:22:59 +08:00
    @sherlocktheplant 你的方法能取到文本“娱乐”,但是取不到<p>啊,而且标签也不固定,不一定是<p>,还有其他的。
    xucuncicero
        21
    xucuncicero  
       2016-10-03 14:49:27 +08:00
    ```python3
    soup = BeautifulSoup(html, 'html.parser')
    theTag = soup.find_all(text='娱乐')
    for tag in theTag:
    print(tag.find_parent("p"))
    ```
    xucuncicero
        22
    xucuncicero  
       2016-10-03 14:50:35 +08:00
    2 楼的没问题,你说报错,具体是啥
    Kisesy
        23
    Kisesy  
       2016-10-03 16:52:36 +08:00
    b = BeautifulSoup("""<p id="a1">新闻</p><p id="a2">娱乐</p><div id="a3">娱乐</div>""")
    print(b.find_all(True, text='娱乐'))

    额,标签不固定的话写个 True 不就行了。。。
    输出 [<p id="a2">娱乐</p>, <div id="a3">娱乐</div>]
    sherlocktheplant
        24
    sherlocktheplant  
       2016-10-03 18:37:49 +08:00
    @omg21 可以 得到的字符串不是一般的字符串 是 NavigatableString 所有可以直接通过 parent 属性访问到标签 我那个 gist 你运行一下就懂了
    omg21
        25
    omg21  
    OP
       2016-10-03 18:47:16 +08:00
    @practicer 已搞定,就是用你的方法,谢谢
    omg21
        26
    omg21  
    OP
       2016-10-03 18:47:54 +08:00
    @xucuncicero 是的,是我自己搞错了
    practicer
        27
    practicer  
       2016-10-03 20:05:27 +08:00
    @omg21 不客气
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2960 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:39 · PVG 22:39 · LAX 06:39 · JFK 09:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.