6
votes

Mécaniser: trop de valeurs à décompresser (attendu 2)

J'ai essayé d'écrire le code suivant, j'essaie d'écrire un code en Python 3.7 qui ouvre juste un navigateur Web et le site Web lui est alimenté dans la ligne de commande code>:

Exemple.py

browser.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36')]

J'ai entré la commande suivante dans la cmd : p>

Traceback (most recent call last):
  File "Example.py", line 19, in <module>
    browser.open(i)
  File "C:\Python37\lib\site-packages\mechanize\_mechanize.py", line 253, in open
    return self._mech_open(url_or_request, data, timeout=timeout)
  File "C:\Python37\lib\site-packages\mechanize\_mechanize.py", line 283, in _mech_open
    response = UserAgentBase.open(self, request, data)
  File "C:\Python37\lib\site-packages\mechanize\_opener.py", line 188, in open
    req = meth(req)
  File "C:\Python37\lib\site-packages\mechanize\_urllib2_fork.py", line 1104, in do_request_
    for name, value in self.parent.addheaders:
ValueError: too many values to unpack (expected 2)

Et j'ai le suivi suivant:

python Example.py https://www.google.com

Je suis très nouveau dans Python . C'est mon premier code ici. Je suis coincé avec le traçage ci-dessus mais je n'ai pas encore trouvé la solution. J'ai également recherché beaucoup de questions sur la communauté SO mais elles n'ont pas semblé m'aider. Que dois-je faire ensuite?

MISE À JOUR:

Comme suggéré par @ Jean-François-Fabre, dans sa réponse, j'ai ajouté 'User-agent' à l'en-tête, maintenant il n'y a pas de traceback, mais il y a toujours un problème où mon lien ne peut pas être ouvert dans le navigateur.

Voici comment le addheader ressemble maintenant à:

import sys

from mechanize import Browser
browser = Browser()

browser.set_handle_equiv(True)
browser.set_handle_gzip(True)
browser.set_handle_redirect(True)
browser.set_handle_referer(True)
browser.set_handle_robots(False)

# pretend you are a real browser
browser.addheaders = [('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36')]

listOfSites = sys.argv[1:]
for i in listOfSites:
    browser.open(i)


0 commentaires

5 Réponses :


1
votes

Je ne sais pas du tout mécaniser , mais la traceback et les noms de variables (et quelques recherches sur Google) peuvent aider.

Vous initialisez addheaders avec un liste de chaînes. Quelques autres exemples (ex: Mechanize Python et méthode addheader - comment puis-je connaître les en-têtes les plus récents? ) affiche une liste de tuple s, qui semblent correspondre à la traceback. Ex:

for name, value in whatever.addheaders:

pour qu'il se décompose correctement en nom et valeur en boucle

browser.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]


11 commentaires

J'ai ajouté 'User-agent' à l'en-tête, maintenant le code fonctionne correctement, il n'y a pas de traceback, mais le lien n'est toujours pas ouvert dans le navigateur.


Merci beaucoup pour cette mise à jour listOfSites = sys.argv [1:]


cela n'aide probablement pas beaucoup pour votre problème


votre question a maintenant un score de +3, si elle ne répond pas, vous pouvez placer une prime dans quelques-uns. Il pourrait en avoir besoin pour attirer plus de lecteurs. Remarque: ma réponse ne serait pas éligible (et elle n'a pas besoin de l'être)


Oui, c'est ce que je pense faire depuis, personne ne répond correctement au problème de la mécanisation.


Je pense qu'il n'y a pas de réponse telle quelle, mais les gens peuvent commenter et demander des précisions plus tard. Même 50 attire beaucoup de monde


oui, mais personne ne fait ça non plus, donc la dernière option est une prime. Bien que j'aie trouvé un moyen de contourner ce problème en utilisant la bibliothèque de navigateur Web


En utilisant webbrowser.open_new_tab (i) au lieu de browser.open (i)


peut-être pourrez-vous alors répondre à votre propre question, avec cette solution


Ouais laisse moi essayer ça


Je viens de répondre à ma propre question



3
votes

Je viens de trouver un moyen de contourner ce problème, même si le problème ci-dessus existe toujours. Je publie ceci uniquement pour informer les lecteurs que nous pouvons également le faire de cette façon:

Au lieu d'utiliser le package mécanize , nous pouvons utiliser le package webbrowser et écrivez le code python suivant dans le Example.py final:

python Example.py https://www.google.com https://www.bing.com

Ensuite, nous pouvons exécuter ce code python en exécutant la commande suivante dans le terminal / commande prompt:

import webbrowser
import sys

#This is an upgrade suggested by @Jean-François Fabre
listOfSites = sys.argv[1:]

for i in listOfSites:
    webbrowser.open_new_tab(i)

Cette commande mentionnée ci-dessus dans l'exemple ouvrira deux sites à la fois. L'un est Google et l'autre Bing


2 commentaires

C'est la solution correcte car mécaniser n'ouvre pas d'interface utilisateur graphique (AFAIK).


@ThomasHesse êtes-vous sûr, parce que lorsque j'essayais de faire l'implémentation ci-dessus, l'une des méthodes parmi d'autres était d'utiliser Mechanize . Et le code a fonctionné pendant un certain temps, mais le lendemain, lorsque j'ai essayé d'exécuter le code, ce problème s'est produit, je ne sais pas ce qui s'est passé en une seule nuit.



-1
votes

Identique à ci-dessus. Je suppose que je n'ai pas lu toutes les réponses avant de creuser. LOL

import sys
import webbrowser

from mechanize import Browser
browser = Browser()

browser.set_handle_equiv(True)
browser.set_handle_gzip(True)
browser.set_handle_redirect(True)
browser.set_handle_referer(True)
browser.set_handle_robots(False)

# pretend you are a real browser
browser.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36')]

listOfSites = sys.argv[1:]
for i in listOfSites:
    webbrowser.open(i)


1 commentaires

Cela n'a pas aidé. Sinon, ce ne sera pas une question



1
votes

Permettez-moi de répondre à votre question en plusieurs parties:

  • Vous avez raison d'ajouter des "en-têtes de navigateur". De nombreux serveurs peuvent carrément interrompre votre connexion, car c'est un signe certain d'être exploré par un robot.

  • mécaniser comme indiqué par la documentation "est un outil de navigation Web programmatique" .
    Cela signifie qu'il est principalement utilisé pour explorer des pages Web, analyser leur contenu, remplir des formulaires, cliquer sur des éléments, envoyer des demandes, mais pas en utilisant un "vrai" navigateur Web, avec des éléments tels que le rendu CSS. Par exemple, vous ne pouvez pas ouvrir une page et prendre une capture d'écran, car il n'y a pas quelque chose de "rendu", et pour ce faire, vous devez enregistrer la page et la rendre en utilisant une autre solution.

  • Si cela répond à vos besoins, consultez navigateurs headless en tant que technologie, il existe beaucoup d'entre eux. Dans l'écosystème Python, autre que mécaniser , je vérifierais "headless chrome" , car "phantomjs" n'est malheureusement plus disponible. p>

Mais si je comprends bien, vous avez besoin du navigateur Web réel pour ouvrir la page Web, n'est-ce pas? Pour cette raison, vous avez réellement besoin d'un navigateur dans votre système pour vous en occuper!

Cas 1: utilisez le navigateur de votre système natif

Découvrez où se trouve l'exécutable de votre navigateur dans votre système. Par exemple, mon exécutable Firefox se trouve dans "C: \ Program Files \ Mozilla Firefox \ firefox.exe" et ajoutez-le à votre PATH .

Lorsque vous utilisez Windows, utilisez le menu Démarrer pour accéder à Paramètres système avancés -> Avancé -> Variables d'environnement , et ajoutez le chemin ci-dessus à votre variable PATH .

Si vous utilisez Linux export PATH = $ PATH: "/ chemin / vers / votre / navigateur" s'occupera des choses.

Ensuite, votre code peut s'exécuter aussi simplement que

from selenium import webdriver
import sys

listOfSites = sys.argv[1:]
for i in listOfSites:
    driver = webdriver.Firefox()
    driver.get('http://'+i)
    driver.save_screenshot(i+'-screenshot.png')

# When you're finished
# driver.quit()

Firefox ouvrira de nouvelles fenêtres, une pour chacun des liens que vous avez fournis.

Cas 2: Utiliser du sélénium

Vient ensuite le Selenium , qui, à mon avis, est la solution la plus mature aux problèmes liés au navigateur, et ce que la plupart des gens utilisent. Je l'ai utilisé dans un cadre de production avec de très bons résultats. Il fournit à la fois l'interface utilisateur / frontend d'un navigateur qui rend les pages Web, mais vous permet également de travailler par programmation avec ces pages Web.

Il nécessite une configuration, (par exemple, si vous utilisez Firefox, vous vous devrez télécharger l'exécutable geckodriver depuis leur page des versions , puis ajoutez à nouveau votre variable PATH .

Ensuite, vous définissez votre pilote Web, en créez un pour chacun des sites Web que vous devez visiter et obtenez la page Web. Vous pouvez également prendre une capture d'écran, comme preuve que la page a été rendue correctement.

import subprocess
import sys

listOfSites = sys.argv[1:]
links = ""
for i in listOfSites:
    links += "-new-tab " + i
print(links)
subprocess.run(["firefox", links])

J'ai testé ces deux extraits de code et ils fonctionnent comme prévu . S'il vous plaît laissez-moi savoir comment tout cela sonne, et si vous avez besoin de plus d'informations supplémentaires ..! ^^


10 commentaires

J'essaie juste de créer un script pour surfer sur le net, ce n'est pas une dépendance d'utiliser un navigateur Web réel, et Selenium est quelque chose qui est principalement utilisé par les testeurs d'automatisation, je dois principalement me concentrer sur python car c'est quelque chose que je dois apprendre au mieux pour le développement de l'IA. Pouvez-vous s'il vous plaît expliquer comment puis-je éviter un navigateur réel tout en surfant sur le net?


En quoi consiste "surfer sur le net"? Si vous souhaitez rendre et afficher les pages Web, vous avez besoin d’un navigateur, et je ne pense pas que vous puissiez remplacer sa fonctionnalité (ou du moins je ne connais pas de moyen). Si vous voulez simplement explorer d'URL en URL et obtenir uniquement le HTML, mécaniser ou webbrowser sont bons à utiliser, mais je vous recommande également de regarder les requêtes , mais vous n'aurez pas d'interface utilisateur graphique. Le sélénium est en effet principalement utilisé pour les tests d'automatisation, mais il est assez simple à comprendre, et je pense qu'il a ses utilisations pour d'autres tâches dans l'industrie.


C'est bon, je n'ai pas besoin d'une interface graphique, tout ce dont j'ai besoin est de rechercher et d'obtenir le résultat de la recherche et de traiter les données du formulaire, quelles données doivent être transmises et quelle devrait être la valeur dont j'ai besoin pour cette requête ... c'est ce que j'espère pour surfer sur le net


Comment puis-je utiliser le package mechanize / webbrowser / requests pour cela, car je suis très nouveau dans Python. Existe-t-il un lien ou une API auquel je me réfère pour la référence de ces packages?


Ah, d'accord, maintenant je comprends mieux vos exigences, merci pour la clarification! Pour votre cas d'utilisation spécifique, la meilleure chose IMO, c'est en effet mécaniser . Conservez la documentation officielle à proximité, ainsi que la ces et ces tutoriels, et commencez à pirater! StackOverflow est également là pour les questions


Dernière chose, si vous avez besoin de charger et d'exécuter du javascript dans vos pages Web, Selenium est un must, mais pour l'instant, je pense que vous êtes libre de l'ignorer.


Je n'ai pas besoin de charger Javascript dans la page Web, j'essaie juste de créer un bot qui peut surfer sur le net, voyons ce que je peux explorer d'autre en faisant cela. Je suis très enthousiaste à l'idée d'en savoir plus sur l'IA et comment en créer une avec Python.


Amusez-vous bien! L'analyse des sentiments dans les pages Web est une bonne idée qui peut être explorée et pourrait être simple si vous disposez des données analysées. La liste Top 500 d'Alexa est un bon point de départ.


existe-t-il un moyen de déboguer le script python dans notepad ++, ou pouvez-vous me suggérer un autre éditeur python qui peut également m'aider à déboguer le code?


Notepad ++ (et la plupart des éditeurs de texte) ne fournissent pas de capacités de débogage AFAIK, vous devez donc utiliser pdb , gdb pour déboguer à partir de la ligne de commande, ou un bon IDE Python tel que Pycharm, Eclipse, Spyder, vous avez beaucoup de choix.



1
votes

Et voilà :)

import sys
from mechanize import Browser, Request


browser = Browser()

browser.set_handle_equiv(True)
browser.set_handle_gzip(True)
browser.set_handle_redirect(True)
browser.set_handle_referer(True)
browser.set_handle_robots(False)

# setup your header, add anything you want
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.1', 'Referer': 'http://whateveritis.com'}


url_list = sys.argv[1:]
for url in url_list:
    request = Request(url=url, data=None, headers=header)
    response = browser.open(request)
    print(response.read())
    response.close()


8 commentaires

J'ai une erreur en tant que " ModuleNotFoundError: aucun module nommé 'urllib2 "


qu'est-ce que urllib2 ici?


J'ai toujours cette erreur " NameError: le nom 'urllib2' n'est pas défini "


J'ai utilisé votre code mis à jour, j'obtiens toujours une erreur


" NameError: le nom 'urllib2' n'est pas défini " c'est l'erreur


Dois-je installer le package Request manuellement pour cela?


Mise à jour avec uniquement la bibliothèque mécaniser


Merci mec, cela a fonctionné aussi, mais la réponse que je cherchais était la meilleure de @hyperTrashPanda, mais vos mises à jour étaient les mieux adaptées, +1 pour cela