Advertisement
rs6000

crawler_meizitu_06_Proxy_Sqlite

Mar 6th, 2017
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.40 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Tue Mar  7 04:37:23 2017
  4. @author: SmileHsu
  5. blog:smilehsu.cc
  6. requirements:Windows7、python3.52
  7. """
  8.  
  9. import os, requests, shutil
  10. import sqlite3 as lite
  11. from bs4 import BeautifulSoup
  12. import re, random, time
  13.  
  14. #base_url='http://meizitu.com/a/'
  15. fk=1
  16. all_link=[]
  17. error_page=[]
  18. dir_path='d:\meizitu'
  19. sqlite_path='d:\meizitu\meizituDB.sqlite'
  20.  
  21.  
  22. class Downloader(object):
  23.  
  24.     def __init__(self):
  25.         self.ip_pool=[]
  26.         html=requests.get('http://haoip.cc/tiqu.htm')
  27.         iplistn = re.findall(r'r/>(.*?)<b', html.text, re.S)
  28.  
  29.         for ip in iplistn:
  30.             i = re.sub('\n','', ip)
  31.             self.ip_pool.append(i.strip())
  32.        
  33.         self.user_agent_pool=["Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
  34.  "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
  35.  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
  36.  "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
  37.  "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
  38.  "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
  39.  "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
  40.  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
  41.  "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
  42.  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3"
  43.         ]
  44.  
  45.     def get_user_agent(self):
  46.         return random.choice(self.user_agent_pool)
  47.  
  48.     def get_url(self, url):
  49.         ua = self.get_user_agent()
  50.         return self.get_url_with_chosen_agent(url, ua)
  51.        
  52.     def get_url_with_chosen_agent(self, url, agent):
  53.        headers = {'User-Agent': agent}
  54.        response = requests.get(url, headers=headers)
  55.        return response
  56.    
  57.     def get(self, url, timeout, proxy=None, num_retries=6,stream=True):
  58.         print('開始擷取: {}'.format(url))
  59.         ua=random.choice(self.user_agent_pool)
  60.         headers={'User-Agent':ua}
  61.        
  62.         #
  63.         if proxy==None:
  64.             try:
  65.                 return requests.get(url,headers=headers,timeout=timeout,stream=stream)
  66.            
  67.             except:
  68.                 if num_retries>0:
  69.                     time.sleep(10)
  70.                     print('擷取網頁出錯10秒後,再嘗試{}次擷取'.format(num_retries))
  71.                     return self.get(url,timeout,num_retries-1,stream)
  72.                
  73.                 else:
  74.                     print('開始使用prxoy')
  75.                     time.sleep(10)
  76.                     ip=''.join(str(random.choice(self.ip_pool)).strip())
  77.                     proxy={'http':ip}
  78.                     return self.get(url, timeout, proxy,stream)
  79.         #
  80.         else:
  81.             try:
  82.                 ip=''.join(str(random.choice(self.ip_pool)).strip())
  83.                 proxy={'http':ip}
  84.                 return requests.get(url, headers=headers, proxies=proxy, timeout=timeout,stream=stream)
  85.            
  86.             except:
  87.                 if num_retries>0:
  88.                     time.sleep(10)
  89.                     ip=''.join(str(random.choice(self.ip_pool)).strip())
  90.                     proxy={'http':ip}
  91.                     print('正在更換proxy,10秒後再嘗試{}次擷取'.format(num_retries))
  92.                     print('目前使用的proxy:{}'.format(proxy))
  93.                     return self.get(url, timeout, proxy, num_retries-1,stream)
  94.                        
  95.                 else:
  96.                     print('取消使用proxy')
  97.                     res=requests.get(url)
  98.                     return res.text
  99.  
  100. #sql語法
  101. #如果資料庫已經album資料表就刪掉它
  102. sql1="DROP TABLE IF EXISTS 'album';"
  103. #建立新的 album資料表
  104. sql2="CREATE TABLE 'album' ('id' INTEGER PRIMARY KEY  NOT NULL , 'title' VARCHAR);"
  105. #如果資料庫已經album_images資料表就刪掉它
  106. sql3="DROP TABLE IF EXISTS 'album_imags';"
  107. #建立新的 album_images資料表
  108. #FOREIGN KEY(album_id) REFERENCES album(id) 設定 album_id為Foreign Key,跟album資料表中的id連結
  109. sql4="CREATE TABLE 'album_imags' ('img_id' INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL , 'album_id' INTEGER NOT NULL ,\
  110. 'title' VARCHAR NOT NULL , 'img_src' VARCHAR NOT NULL ,FOREIGN KEY(album_id) REFERENCES album(id) );"
  111.  
  112. #資料庫連線,如果路徑底下沒有meizituDB.sqlite則會自動建立
  113. conn= lite.connect(sqlite_path)
  114.  
  115. #再爬蟲程式開始運作前,先建立資料庫
  116. cur=conn.cursor()
  117. cur.execute(sql1)
  118. cur.execute(sql2)
  119. cur.execute(sql3)
  120. cur.execute(sql4)
  121. conn.commit()
  122. conn.close()
  123.  
  124. class meizitu(Downloader):
  125.  
  126.     def all_url(self,url,maxpage):
  127.         for i in range(1,maxpage+1):
  128.             page_url=url+str(i)+'.html'
  129.             all_link.append(page_url)
  130.        
  131.         #計數器
  132.         counter=1
  133.         for p in all_link:
  134.             html=request.get(p,6)
  135.             html.encoding='gb2312'
  136.             soup=BeautifulSoup(html.text,'lxml')
  137.            
  138.             try:
  139.                 #取得頁面的title跟該頁面的圖片連結
  140.                 title=soup.find('div',{'class':'metaRight'}).find('a')
  141.                 #取得圖片連結
  142.                 img_url=soup.find('div',{'class':'postContent'}).find_all('img')
  143.                
  144.                 #測試用 印出頁面的title
  145.                 #print(title.text)
  146.                
  147.                 #測試用
  148.                 #print(len(img_url),img_url)
  149.                
  150.                 #要存圖片的資料夾檔名就用頁面的title
  151.                 dirname=title.text
  152.                
  153.                 #寫入資料庫
  154.                 album_sql="insert or ignore into album values({},'{}');".format(counter,dirname)
  155.                 #測試sql語法
  156.                 #print('insert_sql=',album_sql)
  157.                              
  158.                 conn= lite.connect(sqlite_path)
  159.                 cur=conn.cursor()
  160.                 cur.execute(album_sql)
  161.                 conn.commit()
  162.                 conn.close()
  163.                
  164.                 #建立資料夾
  165.                 self.mkdir(dirname)
  166.                
  167.                 fk=counter
  168.                 #check fk value in main()
  169.                 #print('main()裡的fk值',fk)
  170.                
  171.                 #儲存圖檔
  172.                 self.save(img_url,dirname,fk)
  173.                
  174.                 counter+=1
  175.                
  176.             except Exception as e:
  177.                 print('error: {}'.format(e))
  178.                 error_page.append(p)
  179.                 pass
  180.            
  181.     #def request(self,url):
  182.     #    headers = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}
  183.     #    res = requests.get(url, headers=headers,stream=True)
  184.     #    res.encoding='gb2312'
  185.     #    return res
  186.    
  187.     def mkdir(self, dirname):
  188.         dirname=dirname.strip()
  189.         DisExists = os.path.exists(os.path.join(dir_path, dirname))
  190.         mydir_path=os.path.join(dir_path, dirname)
  191.  
  192.        
  193.         if DisExists==0:
  194.             print('建立資料夾:'+mydir_path)
  195.             os.makedirs(mydir_path)
  196.             os.chdir(mydir_path)
  197.             return True
  198.  
  199.         else:
  200.             print('資料夾已存在'+mydir_path)
  201.             os.chdir(mydir_path)
  202.             return False
  203.    
  204.     def save(self, img_url,dirname,fk):
  205.         #check fk value in save()
  206.         #print('save()裡的 fk值=',fk)
  207.        
  208.         for pic in img_url:
  209.             #路徑check
  210.             #print('目前工作目錄:'+os.getcwd())
  211.            
  212.             #頁面裡的圖片連結
  213.             pic_src=pic['src']
  214.             #測試用
  215.             #print('要下載的圖檔連結'+pic_src)
  216.            
  217.             #下載圖片後要存檔的檔名
  218.             pic_name=pic_src.split('/')[-1]
  219.                      
  220.             #寫入資料庫
  221.             img_sql="INSERT INTO album_imags (album_id,title,img_src) VALUES ({},'{}','{}');".format(fk,dirname,pic_src)
  222.             #check sql語法
  223.             #print('table img sql=',img_sql)
  224.             #寫入資料庫
  225.             conn= lite.connect(sqlite_path)
  226.             cur=conn.cursor()
  227.             cur.execute(img_sql)
  228.             conn.commit()
  229.             conn.close()
  230.            
  231.             #下載圖片後要存檔的檔名
  232.             #檢查檔案是否已經存存在
  233.             #存檔的名稱與下載的圖檔名稱一樣
  234.             #所以可以判斷是否已經下載過
  235.             FisExists = os.path.exists(pic_name)
  236.             if FisExists ==1:
  237.                 print('檔案{}已存在'.format(pic_name))
  238.             else:
  239.                 #下載圖片
  240.                 print('開始下載{}'.format(pic_name))
  241.                
  242.                 #先停用下載功能
  243.                 get_pic=request.get(pic_src,6,proxy=1)
  244.                 f=open(pic_name,'wb')
  245.                 shutil.copyfileobj(get_pic.raw,f)
  246.                 f.close()
  247.                 del get_pic
  248.  
  249. request=Downloader()
  250. Meizitu=meizitu()
  251. Meizitu.all_url(url='http://meizitu.com/a/',maxpage=5)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement