我正在研究如何在互联网上处理新闻文本。所以,我正在编写一个程序,通过新闻网址在数据库中获取和存储新闻。
例如,这是一个随机的news url(西班牙新闻网站)。所以,我正在使用BeautifulSoup
来获取HTML内容,经过一些简单的过程后,我得到了有关新闻的新闻标题,摘要,内容,类别和更多信息。
但是,正如您在示例中使用的新闻中所看到的,还有一些“社交网络”信息(新闻图片的右侧):
我也想获取这些信息,所以我尝试处理该部分的HTML内容,但它不存在!这就是我所做的:
>>> import urllib
>>> from BeautifulSoup import BeautifulSoup as Soup
>>> news = urllib.urlopen('http://elcomercio.pe/mundo/1396187/noticia-horror-eeuu-cinco-ninos-muertos-deja-tiroteo-escuela-religiosa')
>>> soup = Soup(news.read())
>>> sociales = soup.findAll('ul', {'class': 'sociales'})[0].findAll('li')
>>> len(sociales)
3
这是Facebook部分的HTML内容:
>>> sociales[0] # facebook
<li class="top">
<div class="fb-plg">
<div id="fb-root"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=224939367568467";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
<div class="fb-like" data-href="http://elcomercio.pe/noticia/1396187/horror-eeuu-cinco-ninos-muertos-deja-tiroteo-escuela-religiosa" data-send="false" data-layout="box_count" data-width="70" data-show-faces="false" data-action="recommend"></div></div></li>
Twitter部分:
>>> sociales[1] # twitter
<li><a href="https://twitter.com/share" class="twitter-share-button" data-count="vertical" data-via="elcomercio" data-lang="es">Tweet</a><script type="text/javascript" src="//platform.twitter.com/widgets.js"></script></li>
Google+部分:
>>> sociales[2] # google+
<li><script type="text/javascript" src="https://apis.google.com/js/plusone.js">
{lang: 'es'}
</script><g:plusone size="tall"></g:plusone></li>
正如您所看到的,我正在寻找的信息不包含在HTML内容中,我猜它是通过某种API链接获得的。
所以我的问题是:无论如何我可以从某个新闻的HTML内容中获取我正在寻找的信息(推荐的数量,推文数量,+ 1的数量)?
答案 0 :(得分:2)
这是我的解决方案。我发布它是因为也许有一天会有人遇到同样的问题。我关注了@Hoff建议,并使用了phantomjs
。
首先我安装它(Linux,Windows或MacOS,无关紧要)。您只需要能够在提示/控制台中将其作为命令运行,如:
phantomjs file.js
这是phantomjs installation guide。
然后,我创建了一个简单的脚本,它接收一个url并返回一个BeautifulSoup
对象(在执行所有的javascript之后):
import os
import os.path
import hashlib
import subprocess
from BeautifulSoup import BeautifulSoup
PHANTOM_DIR = os.path.join(os.getcwd(), 'phantom')
try:
os.stat(PHANTOM_DIR)
except OSError:
os.mkdir(PHANTOM_DIR)
PHANTOM_TEMPLATE = """var page = require('webpage').create();
page.open('%(url)s', function (status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
var p = page.evaluate(function () {
return document.getElementsByTagName('html')[0].innerHTML
});
console.log(p);
}
phantom.exit();
});"""
def get_executed_soup(url):
""" Returns a BeautifulSoup object with the parsed HTML of the url
passed, after executing all the scripts in it. """
file_id = hashlib.md5(url).hexdigest()
PHANTOM_ABS_PATH = os.path.join(PHANTOM_DIR, 'phantom%s.js' % file_id)
OUTPUT_ABS_PATH = os.path.join(PHANTOM_DIR, 'output%s.html' % file_id)
phantom = open(PHANTOM_ABS_PATH, 'w')
phantom.write(PHANTOM_TEMPLATE % {'url': url})
phantom.close()
cmd = 'phantomjs ' + PHANTOM_ABS_PATH + ' > ' + OUTPUT_ABS_PATH
stdout, stderr = subprocess.Popen(cmd, shell=True).communicate()
output = open(OUTPUT_ABS_PATH, 'r')
soup = BeautifulSoup(output.read())
output.close()
os.remove(PHANTOM_ABS_PATH)
os.remove(OUTPUT_ABS_PATH)
return soup
就是这样!
PS:我只在Linux上测试过,所以如果您在Windows和/或MacOS上尝试过此操作,请分享您的“体验”。谢谢:))
PS 2:我也在Windows中测试过,就像魅力一样!
我也在personal blog发布了这个:)
答案 1 :(得分:1)
您使用的客户端(urllib)不会执行任何javascript,大多数社交插件都会使用它来显示您想要的数据。
您需要的是能够运行javascipt的客户端,phantomjs是一个不错的选择,here's a good explanation on how to do just what you want。