在 Python 中使用 BeautifulSoup 从脚本标签中提取文本

Posted

技术标签:

【中文标题】在 Python 中使用 BeautifulSoup 从脚本标签中提取文本【英文标题】:Extracting text from script tag using BeautifulSoup in Python 【发布时间】:2014-09-26 12:25:43 【问题描述】:

我希望使用 Beautiful soup(Python) 从 SCRIPT 标记中的以下代码(不在正文中)中提取电子邮件、电话和姓名值。我看到美汤可以用来提取。

我尝试使用以下代码获取页面 -

fileDetails = BeautifulSoup(urllib2.urlopen('http://www.example.com').read())
results = fileDetails.find(email:")

此 Ajax 请求代码不再在页面中重复。我们是否也可以编写try和catch,这样如果在页面中没有找到它就不会抛出任何错误。

<script type="text/javascript" language='javascript'> 
$(document).ready( function ()
   
   $('#message').click(function()
       alert();
   );

    $('#addmessage').click(function()
        $.ajax( 
            type: "POST",
            url: 'http://www.example.com',
            data:  
                email: 'abc@g.com', 
                phone: '9999999999', 
                name: 'XYZ'
            
        );
    );
);

一旦我得到这个,我也想存储在一个 excel 文件中。

感谢期待。

【问题讨论】:

要么提供一个实际的 url,要么提供相关的 script 标签内容(如果可能的话,更好的 url)。 这是示例。我认为,从 html 文件中查找文本很容易。 很抱歉打扰了,但这并不清楚。如果我们无法看到所需数据在 HTML 中的确切位置,我们该如何提供帮助?请更具体。你问得越好,你在这个话题上得到一个好的和快速的答案的机会就越大。 对此我很抱歉。它在ajax脚本中。脚本发布在问题中。我正在寻找提取“abc@g.com”、“9999999999”和“XYZ”。 【参考方案1】:

除了基于正则表达式的方法之外,您还可以使用 slimit 模块解析 javascript 代码,该模块构建一个抽象语法树并为您提供一种获取所有分配并将它们放入字典的方法:

from bs4 import BeautifulSoup
from slimit import ast
from slimit.parser import Parser
from slimit.visitors import nodevisitor


data = """
<html>
    <head>
        <title>My Sample Page</title>
        <script>
        $.ajax(
            type: "POST",
            url: 'http://www.example.com',
            data: 
                email: 'abc@g.com',
                phone: '9999999999',
                name: 'XYZ'
            
        );
        </script>
    </head>
    <body>
        <h1>What a wonderful world</h1>
    </body>
</html>
"""

# get the script tag contents from the html
soup = BeautifulSoup(data)
script = soup.find('script')

# parse js
parser = Parser()
tree = parser.parse(script.text)
fields = getattr(node.left, 'value', ''): getattr(node.right, 'value', '')
          for node in nodevisitor.visit(tree)
          if isinstance(node, ast.Assign)

print fields

打印:

u'name': u"'XYZ'", u'url': u"'http://www.example.com'", u'type': u'"POST"', u'phone': u"'9999999999'", u'data': '', u'email': u"'abc@g.com'"

在其他领域中,您感兴趣的还有emailnamephone

希望对您有所帮助。

【讨论】:

【参考方案2】:

您可以通过BeautifulSoup 获取script 标签内容,然后应用正则表达式获取所需数据。

工作示例(基于您在问题中描述的内容):

import re
from bs4 import BeautifulSoup

data = """
<html>
    <head>
        <title>My Sample Page</title>
        <script>
        $.ajax(
            type: "POST",
            url: 'http://www.example.com',
            data: 
                email: 'abc@g.com',
                phone: '9999999999',
                name: 'XYZ'
            
        );
        </script>
    </head>
    <body>
        <h1>What a wonderful world</h1>
    </body>
</html>
"""

soup = BeautifulSoup(data)
script = soup.find('script')

pattern = re.compile("(\w+): '(.*?)'")
fields = dict(re.findall(pattern, script.text))
print fields['email'], fields['phone'], fields['name']

打印:

abc@g.com 9999999999 XYZ

我不太喜欢这个解决方案,因为这种正则表达式方法非常脆弱。可能会发生各种会破坏它的事情。我仍然认为有一个更好的解决方案,我们在这里错过了一个更大的图景。提供指向该特定网站的链接会有很大帮助,但它就是这样。


UPD(修复提供的代码 OP):

soup = BeautifulSoup(data, 'html.parser')
script = soup.html.find_next_sibling('script', text=re.compile(r"\$\(document\)\.ready"))

pattern = re.compile("(\w+): '(.*?)'")
fields = dict(re.findall(pattern, script.text))
print fields['email'], fields['phone'], fields['name']

打印:

abcd@gmail.com 9999999999 Shamita Shetty

【讨论】:

代码运行起来就像一个魅力。我遇到语法错误。这个小 x 在以下代码中产生了一个问题: 它说,SyntaxError: Non - 第 17 行 import.py 文件中的 ASCII 字符“\xc3”,但未声明编码;详情见python.org/peps/pep-0263.html 添加了这个 # -- coding: utf-8 --import os 并且它工作正常。 嘿@alecxe,我已经更新了脚本。我现在收到一个错误。这是因为 @Chopra 什么错误?我已将您提供的脚本代码粘贴到我的示例中,它可以像以前一样工作。 我刚刚添加了

以上是关于在 Python 中使用 BeautifulSoup 从脚本标签中提取文本的主要内容,如果未能解决你的问题,请参考以下文章

beautifulsoup模块

Beautifulsoup模块

python 抓取图片

python安装Django需要环境

python网络爬虫 - 如何伪装逃过反爬虫程序

[Python3网络爬虫开发实战] 1.3.2-Beautiful Soup的安装