【问题标题】:How to use Beautiful Soup to extract string in <script> tag?如何使用 Beautiful Soup 提取 <script> 标签中的字符串?
【发布时间】:2016-11-27 14:30:10
【问题描述】:

在给定的 .html 页面中,我有一个像这样的脚本标签:

     <script>jQuery(window).load(function () {
  setTimeout(function(){
    jQuery("input[name=Email]").val("name@email.com");
  }, 1000);
});</script>

如何使用 Beautiful Soup 提取电子邮件地址?

【问题讨论】:

    标签: python web-scraping beautifulsoup


    【解决方案1】:

    为了获取&lt;script&gt;标签内的字符串,可以使用.contents.string

    data = """
       <body>
    <script>jQuery(window).load(function () {
      setTimeout(function(){
        jQuery("input[name=Email]").val("name@email.com");
      }, 1000);
    });</script>
     </body>
        """
    soup = BeautifulSoup(data, "html.parser")
    
    script = soup.find("script")
    inner_text_with_string = script.string
    inner_text_with_content = script.contents[0]
    
    print('inner_text_with_string', inner_text_with_string)
    print('inner_text_with_content', inner_text_with_content)
    

    【讨论】:

      【解决方案2】:

      只需几行 gazpacho.split 即可解决此问题,无需正则表达式!

      from gazpacho import Soup
      
      html = """\
      <script>jQuery(window).load(function () {
        setTimeout(function(){
          jQuery("input[name=Email]").val("name@email.com");
        }, 1000);
      });</script>
      """
      
      soup = Soup(html)
      string = soup.find("script").text
      string.split(".val(\"")[-1].split("\");")[0]
      

      哪个会输出:

      'name@email.com'
      

      【讨论】:

        【解决方案3】:

        我遇到了类似的问题,问题似乎是调用script_tag.text 返回一个空字符串。相反,您必须致电script_tag.string。也许这在 BeautifulSoup 的某些版本中有所改变?

        无论如何,@alecxe's answer 对我不起作用,所以我修改了他们的解决方案:

        import re
        
        from bs4 import BeautifulSoup
        
        data = """
        <body>
            <script>jQuery(window).load(function () {
              setTimeout(function(){
                jQuery("input[name=Email]").val("name@email.com");
              }, 1000);
            });</script>
        </body>
        """
        soup = BeautifulSoup(data, "html.parser")
        
        script_tag = soup.find("script")
        if script_tag:
          # contains all of the script tag, e.g. "jQuery(window)..."
          script_tag_contents = script_tag.string
        
          # from there you can search the string using a regex, etc.
          email = re.search(r'\.+val\("(.+)"\);', script_tag_contents).group(1)
          print(email)
        

        这打印出name@email.com

        【讨论】:

        • 我遇到了同样的问题,谢谢,你救了我的命!
        • 感谢string 的提示!这在版本 4.9.0 中必须已更改。变更日志:“嵌入式 CSS 和 Javascript 现在存储在不同的样式表和脚本标签中,这些标签被 get_text() 等方法忽略,因为大多数人不认为这类内容是‘文本’。”
        【解决方案4】:

        要向@Bob's answer 添加更多内容,并假设您还需要在可能有其他script 标记的HTML 中找到script 标记。

        这个想法是定义一个正则表达式,用于locating the element with BeautifulSoup 和提取email 值:

        import re
        
        from bs4 import BeautifulSoup
        
        
        data = """
        <body>
            <script>jQuery(window).load(function () {
              setTimeout(function(){
                jQuery("input[name=Email]").val("name@email.com");
              }, 1000);
            });</script>
        </body>
        """
        pattern = re.compile(r'\.val\("([^@]+@[^@]+\.[^@]+)"\);', re.MULTILINE | re.DOTALL)
        soup = BeautifulSoup(data, "html.parser")
        
        script = soup.find("script", text=pattern)
        if script:
            match = pattern.search(script.text)
            if match:
                email = match.group(1)
                print(email)
        

        打印:name@email.com

        这里我们使用simple regular expression for the email address,但我们可以更进一步,更严格,但我怀疑这对于这个问题实际上是必要的。

        【讨论】:

          【解决方案5】:

          仅使用 BeautifulSoup 是不可能的,但您可以使用 BS + 正则表达式来做到这一点

          import re
          from bs4 import BeautifulSoup as BS
          
          html = """<script> ... </script>"""
          
          bs = BS(html)
          
          txt = bs.script.get_text()
          
          email = re.match(r'.+val\("(.+?)"\);', txt).group(1)
          

          或者像这样:

          ...
          
          email = txt.split('.val("')[1].split('");')[0]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-04-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-09
            • 2020-05-04
            • 1970-01-01
            相关资源
            最近更新 更多