2016-11-07 4 views
0

Ich habe ein Skript basiert weg LiteScraper von Github, zu kratzen Meme und Gifs von http://ifunny.coPython Scraper File Naming

Das Skript speichert alle Bilder in Ordnern mit einem Zeitstempel, zum Beispiel „ifunny- (Timestamp)“

Ich kratze von http://ifunny.co/feeds/shuffle, so bekomme ich eine zufällige Seite mit 10 Bildern jedes Mal.

Das Problem ist, ich muss das Skript so ändern, dass es alle Bilder in einem bestimmten Ordnernamen speichert.

Ich habe versucht, den Code zu entfernen, der den Zeitstempel hinzufügt, aber das Problem ist jedes Mal, wenn es bis zu 10 Bilder und kratzt die nächste Seite, die 10 neuen Bilder überschreiben die älteren Bilder.

Das Skript der Bilder wie "1, 2, 3, 4" ect

Hier ist der Code zu nennen scheint:

import os 
import time 
from html.parser import HTMLParser 
import urllib.request 

#todo: char support for Windows 
#deal with triple backslash filter 
#recursive parser option 


class LiteScraper(HTMLParser): 
    def __init__(self): 
     HTMLParser.__init__(self) 
     self.lastStartTag="No-Tag" 
     self.lastAttributes=[] 
     self.lastImgUrl="" 
     self.Data=[] 
     self.acceptedTags=["div","p","h","h1","h2","h3","h4","h5","h6","ul","li","a","img"] 
     self.counter=0 
     self.url="" 


     self.SAVE_DIR="" #/Users/stjepanbrkic/Desktop/temp 
     self.Headers=["User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"] 

    def handle_starttag(self,tag,attrs): 
     #print("Encountered a START tag:",tag) 
     self.lastStartTag=tag 
     self.lastAttributes=attrs #unnecesarry, might come in hany 

     if self.lastStartTag=="img": 
      attrs=self.lastAttributes 

      for attribute in attrs: 
       if attribute[0]=="src": 
        self.lastImgUrl=attribute[1] 
        print(attribute[1]) 

        #Allow GIF from iFunny to download 
        for attribute in attrs: 
         if attribute[0]=="data-gif": 
          self.lastImgUrl=attribute[1] 
          print(attribute[1]) 
          #End Gif Code 

      self.handle_picture(self.lastImgUrl) 

    def handle_endtag(self,tag): 
     #print("Encountered a END tag:",tag) 
     pass 

    def handle_data(self,data): 
     data=data.replace("\n"," ") 
     data=data.replace("\t"," ") 
     data=data.replace("\r"," ") 
     if self.lastStartTag in self.acceptedTags: 
      if not data.isspace(): 
       print("Encountered some data:",data) 
       self.Data.append(data) 

     else: 
      print("Encountered filtered data.") #Debug 

    def handle_picture(self,url): 
     print("Bumped into a picture. Downloading it now.") 
     self.counter+=1 
     if url[:2]=="//": 
      url="http:"+url 

     extension=url.split(".") 
     extension="."+extension[-1] 

     try: 
      req=urllib.request.Request(url) 
      req.add_header(self.Headers[0],self.Headers[1]) 
      response=urllib.request.urlopen(req,timeout=10) 
      picdata=response.read() 
      file=open(self.SAVE_DIR+"/pics/"+str(self.counter)+extension,"wb") 
      file.write(picdata) 
      file.close() 
     except Exception as e: 
      print("Something went wrong, sorry.") 


    def start(self,url): 
     self.url=url 
     self.checkSaveDir() 

     try: #wrapped in exception - if there is a problem with url/server 
      req=urllib.request.Request(url) 
      req.add_header(self.Headers[0],self.Headers[1]) 
      response=urllib.request.urlopen(req,timeout=10) 
      siteData=response.read().decode("utf-8") 
      self.feed(siteData) 
     except Exception as e: 
      print(e) 

     self.__init__() #resets the parser/scraper for serial parsing/scraping 
     print("Done!") 

    def checkSaveDir(self): 
     #----windows support 
     if os.name=="nt": 
      container="\ " 
      path=os.path.normpath(__file__) 
      path=path.split(container[0]) 
      path=container[0].join(path[:len(path)-1]) 
      path=path.split(container[0]) 
      path="/".join(path) 
     #no more windows support! :P 
     #for some reason, os.normpath returns path with backslashes 
     #on windows, so they had to be supstituted with fowardslashes. 

     else: 
      path=os.path.normpath(__file__) 
      path=path.split("/") 
      path="/".join(path[:len(path)-1]) 

     foldername=self.url[7:] 
     foldername=foldername.split("/")[0] 

     extension=time.strftime("iFunny")+"-"+time.strftime("%d-%m-%Y") + "-" + time.strftime("%Hh%Mm%Ss") 

     self.SAVE_DIR=path+"/"+foldername+"-"+extension 


     if not os.path.exists(self.SAVE_DIR): 
      os.makedirs(self.SAVE_DIR) 

     if not os.path.exists(self.SAVE_DIR+"/pics"): 
      os.makedirs(self.SAVE_DIR+"/pics") 

     print(self.SAVE_DIR) 

und das ist, was ich bin mit dem Skript zu verwenden:

Pastebin dot com/PNwJ9wEJ

Sorry für die Pastebin, es pflegen lassen sie mich meinen Code schreiben ...

Ich bin sehr neu in Python, also bin ich mir nicht sicher, wie das zu beheben ist. Ist es möglich, es so zu machen?

Page 1 Bildname: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) Page 2 Bild Namen: (11, 12, 13 ....)

Antwort

0

Jedes Mal, wenn Ihr Parser instanziiert wird (also für jede neue Seite), wird counter auf Null gesetzt. Deshalb werden die Bilder immer wieder überschrieben.

Eine Alternative wäre zu bestimmen, welche Dateinamen bereits verwendet werden.

i = 0 
while os.path.isfile('your_filename_logic_'+str(i)): 
    i += 1 
# Now i is the first number which hasn't been used. 

Aber wenn Sie Tausende von Bildern zu erhalten, könnte dies nicht so schnell sein, wie Sie wollen würden.

Sie könnten den Zähler in einer Datei speichern, nachdem die LiteScraper beendet, und lesen Sie es zurück, wenn der nächste gestartet wird.

def startMyNewCounter(self): 
    if os.path.isfile('your_filename_logic_' + 'count'): 
     with open('your_filename_logic_'+'count', 'r') as f: 
      self.counter = int(next(f)) 
    else: 
     self.counter = 0 

def saveMyCounter(self): 
    with open('your_filename_logic_'+'count', 'w') as f: 
     f.write(str(self.counter) + '\n') 

Oder die einfachste Antwort: Wenn Sie nicht über Ihre Bilder kümmern, nachdem das Programm schließt, Sie den Zähler eine globale Variable und nicht als Mitglied Ihrer LiteScraper machen könnte. So nimmt jeder neue LiteScraper dort auf, wo der letzte aufgehört hat.