Пробовал Python BeautifulSoup и Phantom JS: STILL не может очистить сайты

Возможно, вы видели мои отчаянные разочарования за последние несколько недель здесь. Я собирал данные о времени ожидания и все еще не могу получить данные с этих двух сайтов

http://www.centura.org/erwait

http://hcavirginia.com/home/

Сначала я попробовал BS4 для Python. Пример кода ниже для HCA Virgina

from BeautifulSoup import BeautifulSoup
import requests

url = 'http://hcavirginia.com/home/'
r = requests.get(url)

soup = BeautifulSoup(r.text)
wait_times = [span.text for span in soup.findAll('span', attrs={'class': 'ehc-er-digits'})]

fd = open('HCA_Virginia.csv', 'a')

for w in wait_times:
    fd.write(w + '\n')

fd.close()

Все, что это делает, это печатает заготовки на консоль или CSV. Так что я попробовал это с PhantomJS, так как кто-то сказал мне, что это может быть загрузка с JS. Тем не менее, тот же результат! Печатает пробелы в консоли или CSV. Пример кода ниже.

var page = require('webpage').create(),
url = 'http://hcavirginia.com/home/';

page.open(url, function(status) {
if (status !== "success") {
    console.log("Can't access network");
} else {
    var result = page.evaluate(function() {

        var list = document.querySelectorAll('span.ehc-er-digits'), time = [], i;
        for (i = 0; i < list.length; i++) {
            time.push(list[i].innerText);
        }
        return time;

    });
    console.log (result.join('\n'));
    var fs = require('fs');
    try 
    {                   
        fs.write("HCA_Virginia.csv", '\n' + result.join('\n'), 'a');
    } 
    catch(e) 
    {
        console.log(e); 
    } 
}

phantom.exit();
});

Те же проблемы с Centura Health:(

Что я делаю неправильно?

1 ответ

Решение

Проблема, с которой вы сталкиваетесь, заключается в том, что элементы создаются JS, и их загрузка может занять некоторое время. Вам нужен скребок, который обрабатывает JS и может подождать, пока необходимые элементы не будут созданы.

Вы можете использовать PyQt4. Адаптировать этот рецепт от webscraping.com и HTML-парсера, такого как BeautifulSoup, довольно просто:

(после того, как я написал это, я нашел библиотеку webscraping для python. Возможно, стоит посмотреть)

import sys
from bs4 import BeautifulSoup
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtWebKit import * 

class Render(QWebPage):
    def __init__(self, url):
        self.app = QApplication(sys.argv)
        QWebPage.__init__(self)
        self.loadFinished.connect(self._loadFinished)
        self.mainFrame().load(QUrl(url))
        self.app.exec_()

    def _loadFinished(self, result):
        self.frame = self.mainFrame()
        self.app.quit()   

url = 'http://hcavirginia.com/home/'
r = Render(url)
soup = BeautifulSoup(unicode(r.frame.toHtml()))
# In Python 3.x, don't unicode the output from .toHtml(): 
#soup = BeautifulSoup(r.frame.toHtml()) 
nums = [int(span) for span in soup.find_all('span', class_='ehc-er-digits')]
print nums

Выход:

[21, 23, 47, 11, 10, 8, 68, 56, 19, 15, 7]

Это был мой оригинальный ответ, используя ghost.py:

Мне удалось кое-что взломать для вас, используя ghost.py. (протестировано на Python 2.7, ghost.py 0.1b3 и PyQt4-4 32-bit). Я не рекомендовал бы использовать это в производственном коде все же!

from ghost import Ghost
from time import sleep

ghost = Ghost(wait_timeout=50, download_images=False)
page, extra_resources = ghost.open('http://hcavirginia.com/home/',
                                   headers={'User-Agent': 'Mozilla/4.0'})

# Halt execution of the script until a span.ehc-er-digits is found in 
# the document
page, resources = ghost.wait_for_selector("span.ehc-er-digits")

# It should be possible to simply evaluate
# "document.getElementsByClassName('ehc-er-digits');" and extract the data from
# the returned dictionary, but I didn't quite understand the
# data structure - hence this inline javascript.
nums, resources = ghost.evaluate(
    """
    elems = document.getElementsByClassName('ehc-er-digits');
    nums = []
    for (i = 0; i < elems.length; ++i) {
        nums[i] = elems[i].innerHTML;
    }
    nums;
    """)

wt_data = [int(x) for x in nums]
print wt_data
sleep(30) # Sleep a while to avoid the crashing of the script. Weird issue!

Некоторые комментарии:

  • Как вы можете видеть из моих комментариев, я не совсем выяснил структуру Ghost.evaluate(document.getElementsByClassName('ehc-er-digits');) - возможно, возможно найти информацию, необходимую с помощью такого запроса.

  • У меня также были некоторые проблемы со сбоем скрипта в конце. Сон в течение 30 секунд исправил проблему.

Другие вопросы по тегам