2011-05-27 4 views
1

Je veux faire un peu de script de base et j'essaye de le faire en javascript. Je veux essentiellement télécharger une page wikiquote et la gratter.Javascript: Télécharger et interagir avec une autre page

Quelle est la meilleure façon de faire cela? Comment puis-je obtenir la page? J'ai essayé de le faire via jQuery.get()

$.get('http://en.wikiquote.org/wiki/Last_words', function(data) { console.log(data); }) 

Mais le journal est tout simplement un objet d'erreur et la console affiche

XMLHttpRequest ne peut pas charger http://en.wikiquote.org/wiki/Last_words. L'origine null n'est pas autorisée par Access-Control-Allow-Origin. en.wikiquote.org/wiki/Last_words

GET http://en.wikiquote.org/wiki/Last_words non définie (non définie)

Je suppose que je ne prends pas la bonne approche. Que devrais-je faire?

De même, une fois que je téléchargerai le fichier, quels outils sont disponibles pour le traverser? XPath? RegEx? Existe-t-il un moyen de générer un modèle DOM à partir de celui-ci et d'attacher jquery?

Une possibilité intéressante serait d'ouvrir une petite fenêtre pop-up qui télécharge la page et ensuite exécuter mon script pour gratter la page et retourner les données. Je suis conscient que cela ressemble beaucoup à l'injection de script. Est-il même possible de le faire d'une manière amicale?

Répondre

4

En supposant que vous vous limitiez à JavaScript dans le navigateur, et que les documents ne se trouvent pas sur le même hôte que la page exécutant le script, vous ne pouvez pas le faire. Le Same Origin security policy rend cela impossible. Sans cela, une page Web pourrait demander des données à partir de n'importe quel site (y compris les sites LAN) auquel l'utilisateur peut accéder, avec son adresse IP, ses cookies, et tout ce qui pourrait être utilisé pour l'authentification. (Toutes vos opérations bancaires nous appartiennent).

+0

Ceci est intéressant et je veux hacker une bibliothèque pour contourner ce problème ... –

+0

+1 pour "Toutes vos opérations bancaires nous appartiennent"! : D – jwueller

1

XMLHttpRequest ne peut pas être utilisé pour les demandes inter-domaines. Vous pouvez charger la page en utilisant un iframe et essayer d'obtenir les détails à partir de là, mais je recommande de faire ce côté serveur (en utilisant un analyseur DOM ou SAX, pour répondre à votre autre question) car le faire en JavaScript n'est clairement pas très élégant .

+0

Hmm ok, un peu surpris de ça –

3

WikiQuote exposes an API. Vous pouvez utiliser JSONP pour faire une demande à l'API et d'obtenir les données toutes préanalysée et prêt à partir:

document.body.appendChild(document.createElement("script")).src = 
    "http://en.wikiquote.org/w/api.php?action=query&titles=Last_words" + 
     "&prop=revisions&rvlimit=1&rvprop=content&format=json&callback=handleQuote"; 

function handleQuote(quote) 
{ 
    // quote is the response from wikiquote 
} 

Notez que la réponse est renvoyée comme balises wiki, pas html. Vous devrez faire un peu d'analyse pour obtenir html, si c'est ce que vous recherchez. Modifier: Utilisez action=parse&page=Last_words pour obtenir html.

Vous pouvez prévisualiser la réponse JSON dans votre navigateur en changeant l'argument format de json à jsonfm et le coller dans votre navigateur:

balisage Wiki:
http://en.wikiquote.org/w/api.php?action=query&titles=Last_words&prop=revisions&rvlimit=1&rvprop=content&format=jsonfm&callback=handleQuote

HTML:
http://en.wikiquote.org/w/api.php?action=parse&page=Last_words&format=jsonfm&callback=handleQuote

Modifier: J'ai vraiment répondu seulement la moitié (ou moins) de votre question. Quant à la façon d'interagir avec les données une fois que vous l'avez, jQuery le rend simple. Si vous passez une chaîne html dans $(), jQuery construit les éléments pour vous. Ensuite, vous pouvez y accéder via des méthodes jQuery ou DOM:

var paragraphs = $(someHTML).find("p"); 

Une façon simple d'obtenir le code HTML de tout domaine via JavaScript, est de faire votre demande ajax à une page de serveur local qui demande le document pour vous. Vous pouvez écrire un gestionnaire générique page ashx, avec quelque chose comme:

public void ProcessRequest(HttpContext context) 
{ 
    string url = Request.QueryString["url"]; 
    if (Uri.IsWellFormedUriString(url, UriKind.Absolute)) 
    { 
     context.Response.Write(new WebClient().DownloadString(url)); 
    } 
} 

Et puis appelez avec jQuery:

var url = encodeURIComponent("http://en.wikiquote.org/wiki/Last_words"); 
$.get("fetch.ashx?url=" + url, function (response) 
{ 
    var $response = $(response); 
}); 

Edit: Les nouveaux navigateurs ne prennent en charge une récupération de données inter-domaines par JavaScript en implémentant Cross-Origin Resource Sharing (CORS). FireFox et Chrome prennent en charge CORS via XMLHttpRequest. IE8 et IE9 prennent en charge CORS avec XDomainRequest. Le hic, c'est que le serveur doit également supporter CORS. En résumé, le serveur doit inclure un en-tête de réponse de Access-Control-Allow-Origin: * pour que le client puisse traiter la réponse. Et malheureusement, il semble que wikiquote n'envoie pas cet en-tête dans sa réponse. Voici un hefty article on the internals of CORS.

+0

Oh, je suppose que j'aurais dû chercher l'API, ça ne m'est même pas venu à l'esprit. Pourtant, j'aimerais savoir comment télécharger des fichiers via des scripts. –

+0

@George - En plus de JSONP, il n'y a pas moyen de contourner la même politique de sécurité d'origine. Mais vous pouvez facilement créer une page de serveur pour demander le contenu, puis faire la demande JavaScript via votre page de serveur: '$ .get ('fetch.ashx? Url =' + encoderURIComponent ('http://en.wikiquote.org/ wiki/Last_words '), function (data) {}); ' – gilly3

+0

Bien sûr, c'est juste dans l'intérêt des scripts en général. Si je tenais à le faire côté serveur, un script ruby ​​ou powershell ferait très bien l'affaire. Je suppose que je pourrais charger un petit iframe minuscule et l'analyser –

Questions connexes