1. 程式人生 > >[Python]公式轉圖片程式最後一個知識點多執行緒ip驗證

[Python]公式轉圖片程式最後一個知識點多執行緒ip驗證

最好的方式是:用多執行緒方式,使用代理去訪問某個網站,然後輸出可用的代理。
python 爬蟲 ip池怎麼做? - Kaito的回答 - 知乎
https://www.zhihu.com/question/47464143/answer/124035743

嗯知道關鍵詞了,搜尋「多執行緒驗證ip」,非常多結果,選擇自己能看懂思路的,大概知道哪一部分是幹什麼的就行。


我選擇了一個http://www.cnblogs.com/sjzh/p/5990152.html

這是他的源程式,模仿的第一步是分析這個源程式,看看這個源程式方不方便改成我要的功能。

import urllib.request
import urllib
import
re import time import random import socket import threading #抓取代理IP ip_totle=[] for page in range(2,6): url='http://ip84.com/dlgn/'+str(page) #url='http://www.xicidaili.com/nn/'+str(page) #西刺代理 headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64)"} request=urllib.request.Request(url=url,headers=headers) response=urllib.request.urlopen(request) content=response.read().decode('utf-8'
) print('get page',page) pattern=re.compile('<td>(\d.*?)</td>') #擷取<td>與</td>之間第一個數為數字的內容 ip_page=re.findall(pattern,str(content)) ip_totle.extend(ip_page) time.sleep(random.choice(range(1,3))) #列印抓取內容 print('代理IP地址 ','\t','埠','\t','速度','\t','驗證時間') for
i in range(0,len(ip_totle),4): print(ip_totle[i],' ','\t',ip_totle[i+1],'\t',ip_totle[i+2],'\t',ip_totle[i+3]) #整理代理IP格式 proxys = [] for i in range(0,len(ip_totle),4): proxy_host = ip_totle[i]+':'+ip_totle[i+1] proxy_temp = {"http":proxy_host} proxys.append(proxy_temp) proxy_ip=open('proxy_ip.txt','w') #新建一個儲存有效IP的文件 lock=threading.Lock() #建立一個鎖 #驗證代理IP有效性的方法 def test(i): socket.setdefaulttimeout(5) #設定全域性超時時間 url = "http://quote.stockstar.com/stock" #打算爬取的網址 try: proxy_support = urllib.request.ProxyHandler(proxys[i]) opener = urllib.request.build_opener(proxy_support) opener.addheaders=[("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64)")] urllib.request.install_opener(opener) res = urllib.request.urlopen(url).read() lock.acquire() #獲得鎖 print(proxys[i],'is OK') proxy_ip.write('%s\n' %str(proxys[i])) #寫入該代理IP lock.release() #釋放鎖 except Exception as e: lock.acquire() print(proxys[i],e) lock.release() #單執行緒驗證 '''for i in range(len(proxys)): test(i)''' #多執行緒驗證 threads=[] for i in range(len(proxys)): thread=threading.Thread(target=test,args=[i]) threads.append(thread) thread.start() #阻塞主程序,等待所有子執行緒結束 for thread in threads: thread.join() proxy_ip.close() #關閉檔案

看下結構就行,程式到大概是兩部分,第一部分抓取ip,第二部分驗證ip。我們自己有抓取ip的程式所以前面可以不要,列表proxys[]用來儲存爬取的ip並且傳遞給第二部分使用,那把我們爬取的ip複製到這裡就行了,注意看看格式,proxy_temp = {"http":proxy_host}人家的格式是字典形式的,OK為了避免改第二部分的程式,我們把ip也改成這種格式,對後面的程式就沒有影響了。

import urllib.request
import urllib
import re
import time
import random
import socket
import threading
#抓取代理IP

#整理代理IP格式
ip_list = ['27.40.146.105:61234', '123.163.154.134:808', '110.200.155.21:8118', '116.192.26.17:1080', '39.72.54.28:8118', '112.93.236.224:9797', '115.46.77.233:8123', '114.231.243.208:30544', '14.153.54.167:3128', '117.66.167.30:8118', '110.73.8.147:8123', '219.136.173.59:9999', '116.31.2.113:8118']
all_ip=[]
proxys=[]
for i in ip_list:
     proxy = {'http':i}
     proxys.append(proxy)
#保證的格式和原來一樣
# proxy_ip=open('proxy_ip.txt','w')  #新建一個儲存有效IP的文件
lock=threading.Lock()  #建立一個鎖
#驗證代理IP有效性的方法
def test(i):
    socket.setdefaulttimeout(5)  #設定全域性超時時間
    url = "http://quote.stockstar.com/stock"  #打算爬取的網址
    try:
        proxy_support = urllib.request.ProxyHandler(proxys[i])
        opener = urllib.request.build_opener(proxy_support)
        opener.addheaders=[("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64)")]
        urllib.request.install_opener(opener)
        res = urllib.request.urlopen(url).read()
        lock.acquire()     #獲得鎖
        print(proxys[i],'is OK')        
        # proxy_ip.write('%s\n' %str(proxys[i]))  #寫入該代理IP
        lock.release()     #釋放鎖
    except Exception as e:
        lock.acquire()
        print(proxys[i],e)
        lock.release()
#單執行緒驗證
'''for i in range(len(proxys)):
    test(i)'''
#多執行緒驗證    
threads=[]
for i in range(len(proxys)):
    thread=threading.Thread(target=test,args=[i])
    threads.append(thread)
    thread.start()
#阻塞主程序,等待所有子執行緒結束
for thread in threads:
    thread.join()

# proxy_ip.close()  #關閉檔案

把我們的ip_list複製過來,修改格式,然後把一下讀寫操作都去掉,我們不要讀寫。執行一下


OK,有錯誤,沒事,有錯誤就對了,通常我們找到的程式都不能直接用,我們試試把提示的錯誤改掉,看看能不能解決。
搜尋「fixture 'i' not found」

我搜索了很多結果,都沒有直接告訴我答案,我都準備換一個程式碼了,我突然想到搜尋過程中錯誤提示是跟一個叫pytest的關鍵詞一起出現,會不會是函式名不能要test?

import urllib.request
import urllib
import re
import time
import random
import socket
import threading
#抓取代理IP

#整理代理IP格式
ip_list = ['27.40.146.105:61234', '123.163.154.134:808', '110.200.155.21:8118', '116.192.26.17:1080', '39.72.54.28:8118', '112.93.236.224:9797', '115.46.77.233:8123', '114.231.243.208:30544', '14.153.54.167:3128', '117.66.167.30:8118', '110.73.8.147:8123', '219.136.173.59:9999', '116.31.2.113:8118']
proxys=[]
for i in ip_list:
     proxy = {'http':i}
     proxys.append(proxy)
#保證的格式和原來一樣
# proxy_ip=open('proxy_ip.txt','w')  #新建一個儲存有效IP的文件
lock=threading.Lock()  #建立一個鎖
#驗證代理IP有效性的方法
def iptest(i):
    socket.setdefaulttimeout(5)  #設定全域性超時時間
    url = "http://quote.stockstar.com/stock"  #打算爬取的網址
    try:
        proxy_support = urllib.request.ProxyHandler(proxys[i])
        opener = urllib.request.build_opener(proxy_support)
        opener.addheaders=[("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64)")]
        urllib.request.install_opener(opener)
        res = urllib.request.urlopen(url).read()
        lock.acquire()     #獲得鎖
        print(proxys[i],'is OK')        
        # proxy_ip.write('%s\n' %str(proxys[i]))  #寫入該代理IP
        lock.release()     #釋放鎖
    except Exception as e:
        lock.acquire()
        print(proxys[i],e)
        lock.release()
#單執行緒驗證
'''for i in range(len(proxys)):
    test(i)'''
#多執行緒驗證    
threads=[]
for i in range(len(proxys)):
    thread=threading.Thread(target=iptest,args=[i])
    threads.append(thread)
    thread.start()
#阻塞主程序,等待所有子執行緒結束
for thread in threads:
    thread.join()

# proxy_ip.close()  #關閉檔案

終於解決了,如果沒有想到我會怎麼做?我會換一個程式繼續修改。模仿會出現各種問題,學習也是在解決問題中進行的,所以遇到問題是好事,如果你複製粘貼後就實現了你的功能,那你其實學到的就很少,但是如果你遇到各種問題,並且解決了一部分,即使還沒成功,你已經在進步了。這次我是再也不會忘記函式名不能叫test了。

最後只需要把我們需要的內容打印出來即可。

import urllib.request
import urllib
import time
import socket
import threading

ip_list=['27.40.146.105:61234', '123.163.154.134:808', '110.200.155.21:8118', '116.192.26.17:1080', '39.72.54.28:8118', '112.93.236.224:9797', '115.46.77.233:8123', '114.231.243.208:30544', '14.153.54.167:3128', '117.66.167.30:8118', '110.73.8.147:8123', '219.136.173.59:9999', '116.31.2.113:8118']

# 驗證代理IP有效性的方法
proxys=[]
all_ip=[]
for i in ip_list:
     proxy = {'http':i}
     # print(type(proxy))
     proxys.append(proxy)

lock = threading.Lock()  # 建立一個鎖
#不可以使用test作為函式或者檔名
def iptest(i):
    socket.setdefaulttimeout(5)  # 設定全域性超時時間
    url = "http://www.baidu.com/"  # 打算爬取的網址
    try:
          proxy_support = urllib.request.ProxyHandler(proxys[i])
          opener = urllib.request.build_opener(proxy_support)
          opener.addheaders = [("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64)")]
          urllib.request.install_opener(opener)
          res = urllib.request.urlopen(url).read()
         # 獲取鎖,用於執行緒同步
          lock.acquire()  # 獲得鎖
          print(proxys[i], 'is OK')
          all_ip.append(str(proxys[i]['http']))
          # 釋放鎖,開啟下一個執行緒
          lock.release()  # 釋放鎖
    except Exception as e:
          lock.acquire()
          print(proxys[i], e)
          lock.release()
    # 單執行緒驗證
# 多執行緒驗證
threads = []
start = time.clock()
# print(len(proxys))
for i in range(len(proxys)):
    thread = threading.Thread(target=iptest, args=[i])
    threads.append(thread)
    thread.start()
# 阻塞主程序,等待所有子執行緒結束
for thread in threads:
    thread.join()


end = time.clock()
print(all_ip)
print("開始時間: %f s" % start)
print("結束時間: %f s" % end)
print("校驗IP耗時: %f s" % (end - start))

完成了功能,高興之餘別忘了再看看程式,這個程式大概意思是,有多少個ip就建立多少個執行緒,然後每個執行緒都執行的是iptest(i)這個函式,就等於是同時執行著多個iptest(i)函式,所以雖然我還不知道執行緒的一些知識,是不是我修改iptest(i)函式,就可以得到並行執行的其他功能呢?又可以做很多有意思的改進了。

到這裡我們的公式轉圖片程式的半自動化功能就全部實現了,你現在有了爬取ip,多執行緒驗證等手段,你已經可以做一個你自己想要的功能了,還等什麼燥起來吧。

關注微信公眾號,回覆【公式圖片】即可獲取原始碼,同時歡迎加我的個人微信進行交流哦。