在Python中使用BeautifulSoup提取script标签中的文本
我想从下面的代码中提取电子邮件、电话和姓名的值,这些代码是在SCRIPT标签里(而不是在页面主体中),我打算使用Beautiful Soup(Python库)来完成这个任务。我发现Beautiful Soup可以用来提取这些信息。
我尝试用以下代码获取页面 -
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文件里。
谢谢你的帮助。
2 个回答
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
我其实不太喜欢这个解决方案,因为用正则表达式的方法很脆弱。很多情况都可能导致它失效。我觉得还有更好的解决办法,我们可能忽略了更重要的事情。如果能提供那个特定网站的链接会帮助很多,但现在就是这样。
更新(修正了提问者提供的代码):
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
8
除了使用正则表达式的方法,你还可以用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'"}
在这些字段中,有email
、name
和phone
是你比较关心的。
希望这对你有帮助。