Сопряжение содержимого на внешнем веб-сайте с записями в базе данных mySQL

tl; dr: я ищу способ найти записи в нашей базе данных, в которых отсутствует информация, получить эту информацию с веб-сайта и добавить ее в запись базы данных.


у нас есть программа управления мультимедиа, которая использует таблицу mySQL для хранения информации. Когда сотрудники загружают носители (видеофайлы, изображения, аудиофайлы) и импортируют их в media manager, они предположим копировать описание СМИ (от исходный веб-сайт) и добавьте его в описание В Media Manager. Однако это не было сделано для тысячи файлов.

имя файла (например. file123.mov) уникален, и страница сведений для этого файла может быть доступна, перейдя по URL-адресу на веб-сайте источника:

website.com/content/ file123

информация, которую мы хотим очистить от этой страницы, имеет идентификатор элемента, который всегда одно и то же.

на мой взгляд, процесс будет такой:

  1. подключиться к базе данных и нагрузка
  2. фильтр: "format" is "Still Image (JPEG)"
  3. фильтр: "description" и "NULL"
  4. получить первый результат
  5. Get "FILENAME" без расширения)
  6. загрузить URL: website.com/content/FILENAME
  7. копировать содержимое элемента "description" (на сайте)
  8. вставить содержимое в "description" (запись SQL)
  9. получить 2-й результат
  10. промыть и повторить, пока не будет достигнут последний результат

мой вопрос(ы):

  1. есть ли программное обеспечение, которое могло бы выполнить такую задачу, или это то, что нужно было бы написать?
  2. если по сценарию, какой был бы лучший тип скрипта (например, я мог бы достичь этого с помощью AppleScript или его нужно было бы сделать на java или php и т. д.)

3 ответов


Я тоже не знаю о каких-либо существующих программных пакетах, которые будут делать все, что вы ищете. Однако Python может подключаться к вашей базе данных, легко выполнять веб-запросы и обрабатывать грязный html. Предполагая, что у вас уже установлен Python, вам понадобятся три пакета:

  • MySQLdb для подключения к базе данных.
  • запросы для легко делать http веб-запросы.
  • BeautifulSoup для надежной разбор html.

вы можете установить эти пакеты с помощью команд pip или установщиков Windows. Соответствующие инструкции находятся на каждом сайте. Весь процесс не займет больше 10 минут.

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

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


  1. есть ли программа, которая могла бы выполнить такую задачу или это то, что нужно по сценарию?

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

  2. если сценарий, что было бы лучшим типом сценария (например, я мог бы достичь этого, используя AppleScript или он должен быть сделан на java или php и т. д.)

    AppleScript не может подключиться к базам данных, поэтому вам обязательно нужно будет бросить что-то еще в микс. Если выбор между Java и PHP (и вы одинаково знакомы с обоими), я бы определенно рекомендовал PHP для этой цели, так как будет значительно меньше кода.

    ваш PHP-скрипт будет выглядеть примерно так:

    $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();
    }
    

PHP-хороший скраппер. Я сделал класс, который обертывает порт cURL PHP здесь:

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

вам, вероятно, придется использовать некоторые из опций:

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

чтобы очистить HTML, я обычно использую регулярные выражения, но вот класс, который я сделал, который должен иметь возможность запрашивать HTML без вопросы:

http://pastebin.com/Jm9jKjAU

использование-это:

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

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

/ / div[@class = 'itm'] / p[last () и text () = 'Hello World']

вы можете использовать это в PHP с классом DOM (встроенный).