J'essaie d'écrire mon premier script Python, et avec beaucoup de Google, je pense que je suis à peu près terminé. Cependant, j'aurai besoin d'aide pour franchir la ligne d'arrivée.Scraper Web multi-thread utilisant urlretrieve sur un site compatible avec les cookies
Je dois écrire un script qui se connecte à un site compatible avec les cookies, racler un tas de liens, puis générer quelques processus pour télécharger les fichiers. J'ai le programme fonctionnant en single-thread, donc je sais que le code fonctionne. Mais, quand j'ai essayé de créer un groupe de travailleurs de téléchargement, j'ai couru dans un mur.
#manager.py
import Fetch # the module name where worker lives
from multiprocessing import pool
def FetchReports(links,Username,Password,VendorID):
pool = multiprocessing.Pool(processes=4, initializer=Fetch._ProcessStart, initargs=(SiteBase,DataPath,Username,Password,VendorID,))
pool.map(Fetch.DownloadJob,links)
pool.close()
pool.join()
#worker.py
import mechanize
import atexit
def _ProcessStart(_SiteBase,_DataPath,User,Password,VendorID):
Login(User,Password)
global SiteBase
SiteBase = _SiteBase
global DataPath
DataPath = _DataPath
atexit.register(Logout)
def DownloadJob(link):
mechanize.urlretrieve(mechanize.urljoin(SiteBase, link),filename=DataPath+'\\'+filename,data=data)
return True
Dans cette révision, le code échoue parce que les témoins ont pas été transférés au travailleur pour urlretrieve à utiliser. Pas de problème, j'ai pu utiliser la classe .cookiejar de mechanize pour enregistrer les cookies dans le manager, et les transmettre au worker.
#worker.py
import mechanize
import atexit
from multiprocessing import current_process
def _ProcessStart(_SiteBase,_DataPath,User,Password,VendorID):
global cookies
cookies = mechanize.LWPCookieJar()
opener = mechanize.build_opener(mechanize.HTTPCookieProcessor(cookies))
Login(User,Password,opener) # note I pass the opener to Login so it can catch the cookies.
global SiteBase
SiteBase = _SiteBase
global DataPath
DataPath = _DataPath
cookies.save(DataPath+'\\'+current_process().name+'cookies.txt',True,True)
atexit.register(Logout)
def DownloadJob(link):
cj = mechanize.LWPCookieJar()
cj.revert(filename=DataPath+'\\'+current_process().name+'cookies.txt', ignore_discard=True, ignore_expires=True)
opener = mechanize.build_opener(mechanize.HTTPCookieProcessor(cj))
file = open(DataPath+'\\'+filename, "wb")
file.write(opener.open(mechanize.urljoin(SiteBase, link)).read())
file.close
Mais, cela ne fonctionne pas parce que ouvre (je pense) veut déplacer le fichier binaire au gestionnaire pour le traitement, et je reçois un message d'erreur « Impossible à l'objet cornichon », se référant à la page Web qu'il essaie de lire dans le fichier. La solution évidente est de lire les cookies du pot de cookie et de les ajouter manuellement à l'en-tête lors de la demande d'urlretrieve, mais j'essaie d'éviter cela, et c'est pourquoi je suis à la recherche de suggestions.
Encore un bogue dans mon code que je posterai comme question future, aucun de mes fils ne sortira correctement. La fonction atexit est là, mais elle ne se déclenche pas, sauf si je la change en décorateur. Mais, alors il perd toutes les variables de session que j'ai utilisées pour me connecter au site en premier lieu! Pour l'instant, il est permis de laisser les huit séances suspendues, mais je devrai revoir la procédure à l'avenir. –