2012-05-23 14 views
6

tl; dr: Estoy buscando una manera de encontrar entradas en nuestra base de datos que faltan, obtener esa información de un sitio web y agregarla a la base de datos entrada.Emparejar contenido en un sitio web externo con entradas en una base de datos mySQL


Tenemos un programa de gestión de medios que utiliza una tabla de MySQL para almacenar la información. Cuando los empleados descargan medios (archivos de video, imágenes, archivos de audio) e importan en el administrador de medios, son supongamos para copiar también la descripción del medio (desde el sitio web de origen) y agregarlo a la descripción en el Administrador de medios. Sin embargo, esto no se ha hecho para miles de archivos. (. Ej file123 .mov)

El nombre del archivo es única y la página de detalles de ese archivo se puede acceder por ir a una dirección URL en la página web fuente:

website.com/content/ file123

la información que queremos para raspar de esa página tiene un ID de elemento que es siempre la misma.

En mi mente el proceso sería:

  1. Conectar a base de datos y Cargar tabla
  2. Filtro: "format" es "Still Image (JPEG)"
  3. Filtro: "description" es "NULL"
  4. Obtener primer resultado
  5. Obtener "FILENAME" sin extensión)
  6. cargar la URL: website.com/content/ FILENAME
  7. Copiar el contenido del elemento "description" (en el sitio web)
  8. pegar contenido en el "description" (entrada SQL)
  9. Get segundo resultado
  10. Enjuague y repita hasta el último resultado se alcanza

Mi pregunta (s) son:

  1. ¿Existe software que podría realizar una tarea, o se trata de algo que tendría que ser guion?
  2. Si está escrito, ¿cuál sería el mejor tipo de secuencia de comandos (por ejemplo, podría lograr esto con AppleScript o tendría que hacerse en Java o PHP, etc.)

Respuesta

1

también yo no tengo conocimiento de ningún paquete de software existentes que va a hacer todo lo que está buscando. Sin embargo, Python puede conectarse a su base de datos, realizar solicitudes web fácilmente y manejar archivos html sucios. Asumiendo que ya ha instalado Python, tendrá tres paquetes:

  • MySQLdb para la conexión a la base de datos.
  • Requests para realizar fácilmente solicitudes web http.
  • BeautifulSoup para un análisis robusto de html.

Puede instalar estos paquetes con comandos pip o instaladores de Windows. Las instrucciones apropiadas están en cada sitio. Todo el proceso no tomará más de 10 minutos.

import MySQLdb as db 
import os.path 
import requests 
from bs4 import BeautifulSoup 

# Connect to the database. Fill in these fields as necessary. 

con = db.connect(host='hostname', user='username', passwd='password', 
       db='dbname') 

# Create and execute our SELECT sql statement. 

select = con.cursor() 
select.execute('SELECT filename FROM table_name \ 
       WHERE format = ? AND description = NULL', 
       ('Still Image (JPEG)',)) 

while True: 
    # Fetch a row from the result of the SELECT statement. 

    row = select.fetchone() 
    if row is None: break 

    # Use Python's built-in os.path.splitext to split the extension 
    # and get the url_name. 

    filename = row[0] 
    url_name = os.path.splitext(filename)[0] 
    url = 'http://www.website.com/content/' + url_name 

    # Make the web request. You may want to rate-limit your requests 
    # so that the website doesn't get angry. You can slow down the 
    # rate by inserting a pause with: 
    #    
    # import time # You can put this at the top with other imports 
    # time.sleep(1) # This will wait 1 second. 

    response = requests.get(url) 
    if response.status_code != 200: 

     # Don't worry about skipped urls. Just re-run this script 
     # on spurious or network-related errors. 

     print 'Error accessing:', url, 'SKIPPING' 
     continue 

    # Parse the result. BeautifulSoup does a great job handling 
    # mal-formed input. 

    soup = BeautifulSoup(response.content) 
    description = soup.find('div', {'id': 'description'}).contents 

    # And finally, update the database with another query. 

    update = db.cursor() 
    update.execute('UPDATE table_name SET description = ? \ 
        WHERE filename = ?', 
        (description, filename)) 

voy a advertir que he hecho un buen esfuerzo para hacer que el código "mirar a la derecha", pero que en realidad no lo he probado. Tendrá que completar los detalles privados.

1

PHP es un buen scrapper. He hecho una clase que envuelve el puerto rizo de PHP aquí:

http://semlabs.co.uk/journal/object-oriented-curl-class-with-multi-threading

es probable que necesite usar algunas de las opciones:

http://www.php.net/manual/en/function.curl-setopt.php

para raspar HTML, por lo general use expresiones regulares, pero aquí hay una clase que hice que debería poder consultar HTML sin problemas:

http://pastebin.com/Jm9jKjAU

Useage es:

$h = new HTMLQuery(); 
$h->load($string_containing_html); 
$h->getElements('p', 'id'); // Returns all p tags with an id attribute 

La mejor opción para raspar sería XPath, pero no puede manejar HTML sucio. Puede usarlo para hacer cosas como:

// div [@class = 'itm']/p [last() and text() = 'Hola mundo'] < - selecciona la última p en elementos div que tiene el innerHTML 'Hello World'

Puede usarlo en PHP con la clase DOM (incorporada).

+0

gracias por la respuesta! ¿Alguna idea de cómo podría tomar la información raspada y relacionarla con las entradas en una tabla mySQL? – OrangeBox

2
  1. ¿Existe software que podría realizar una tarea, o se trata de algo que tendría que ser con guión?

    No estoy al tanto de nada que haga lo que desee de fábrica (e incluso si lo hubiera, la configuración requerida no requerirá mucho menos trabajo que la secuencia de comandos necesaria para rodar su propia solución) .

  2. Si guión, ¿cuál sería el mejor tipo de secuencia de comandos (por ejemplo, ¿podría conseguir esto utilizando AppleScript o sería necesario realizar en Java o PHP, etc.)

    AppleScript no puede conectarse a bases de datos, por lo que definitivamente tendrá que agregar algo más a la mezcla. Si la elección es entre Java y PHP (y usted está igualmente familiarizado con ambos), definitivamente recomendaría PHP para este propósito, ya que habrá considerablemente menos código involucrado.

    su script PHP sería algo como esto:

    $BASEURL = 'http://website.com/content/'; 
    
    // connect to the database 
    $dbh = new PDO($DSN, $USERNAME, $PASSWORD); 
    
    // query for files without descriptions 
    $qry = $dbh->query(" 
        SELECT FILENAME FROM mytable 
        WHERE format = 'Still Image (JPEG)' AND description IS NULL 
    "); 
    
    // prepare an update statement 
    $update = $dbh->prepare(' 
        UPDATE mytable SET description = :d WHERE FILENAME = :f 
    '); 
    
    $update->bindParam(':d', $DESCRIPTION); 
    $update->bindParam(':f', $FILENAME); 
    
    // loop over the files 
    while ($FILENAME = $qry->fetchColumn()) { 
        // construct URL 
        $i = strrpos($FILENAME, '.'); 
        $url = $BASEURL . (($i === false) ? $FILENAME : substr($FILENAME, 0, $i)); 
    
        // fetch the document 
        $doc = new DOMDocument(); 
        $doc->loadHTMLFile($url); 
    
        // get the description 
        $DESCRIPTION = $doc->getElementsById('description')->nodeValue; 
    
        // update the database 
        $update->execute(); 
    } 
    
Cuestiones relacionadas