Получать информацию о социальных сетях из содержимого HTML - PullRequest
2 голосов
/ 03 апреля 2012

Я занимаюсь исследованием обработки новостных текстов в Интернете.Итак, я пишу программу для получения и хранения новостей в БД по новостному URL.

Например, это случайный новостной URL (испанский новостной сайт).Итак, я использую BeautifulSoup для получения HTML-контента, и после небольшого простого процесса у меня есть заголовок, сводка, контент, категория и другая информация о новостях.

Но, как выможно увидеть в новостях, которые я использовал в этом примере, есть также некоторая информация о «социальных сетях» (правая сторона изображения новостей):

  • количество рекомендаций (facebook)
  • количество твитов (твиттер)
  • количество +1 (гугл +)

Я бы тоже хотел получить эту информацию, поэтому я попытался обработать 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

Это HTML-содержание части Facebook:

>>> 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.

Итак, мой вопрос: могу ли я в любом случае получить информацию, которую я ищу (количество рекомендаций на Facebook, количество твитов, количество +1) из содержимого HTML определенной новости?

Ответы [ 2 ]

2 голосов
/ 12 апреля 2012

Вот мое решение.Я публикую это, потому что, возможно, когда-нибудь у кого-то возникнет такая же проблема.Я следовал совету @Hoff и использовал phantomjs.

Итак, сначала я установил его (Linux, Windows или MacOS, не имеет значения).Вы просто должны иметь возможность запустить его как команду в вашей командной строке / консоли, например:

phantomjs file.js

Вот руководство по установке phantomjs .

Затем ясделал простой скрипт, который получает 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, работает как шарм!

Я также опубликовал это в своем личном блоге :)

1 голос
/ 03 апреля 2012

клиент, который вы используете (urllib), не будет выполнять никакой javascript, который используется большинством социальных плагинов для отображения нужных вам данных.

Вам нужен клиент, который способен запускать javascipt, phantomjs - хороший выбор, и вот хорошее объяснение того, как делать то, что вы хотите .

...