天天看點

什麼是反爬蟲和反反爬蟲

對于熟悉爬蟲領域的程式員應該都知道爬取網站圖檔有簡單的幾個步驟:擷取網頁源碼、審閱元素尋找所需資訊、下載下傳并儲存到指定位置。

因為本爬蟲系列曾爬取過頭條上的圖,大部分步驟雷同,這裡主要是針對反爬與反反爬進行拓展,采取子產品化的思路進行程式文檔編寫。

首先,主函數目的就是下載下傳并儲存目标圖檔:

if __name__ == '__main__':
    download_img()
    time.sleep(5)#停止一會,防止頻率過快被封IP或賬号      

主函數中的download_img()函數需要如下代碼中的幾個步驟。按照子產品化的思路,定義get_page函數、find_imgs函數和save_img函數,使得函數架構更加的清晰。

def download_img(folder = 'ooxx',pages = 10):
#包含兩個參數:目标檔案夾;爬取的頁面數量
    os.mkdir(folder)
    os.chdir(folder)
    #建立檔案夾到目标路徑并改變目前工作目錄到指定的路徑
    url = 'http://jshk.com.cn'  
    #待爬取網站的url
    page_num = int(get_page(url))
    #根據url擷取目前頁碼,并改為整形指派給page_num
    for i in range(pages):
        page_num -= i
        page_url = url+ 'page-' + str(page_num) + '#comments'
        #圖檔所在頁面的url
        img_addrs = find_imgs(page_url)
        #根據url找到圖檔,儲存在img_addrs清單中
        save_img(folder, img_addrs)
        #儲存清單中的圖檔到指定目标路徑下的檔案夾      
def url_open(url):
    req = urllib.request.Request(url)
    req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36')
    # ~ proxies = ['125.120.201.62:808',    
    # ~ '183.159.91.240:18118',  
    # ~ '171.12.182.238:26316',
    # ~ ]
    # ~ proxy = random.choice(proxies)
    # ~ proxy_support = urllib.request.ProxyHandler({'http':proxy})
    # ~ opener = urllib.request.build_opener(proxy_support)
    # ~ urllib.request.install_opener(opener)
    response = urllib.request.urlopen(url)
    html = response.read()
    return html      
def get_page(url):
    # 傳回頁面
    html = url_open(url).decode('utf-8')
    a = html.find('current-comment-page') + 23
    # 返這裡沒有用正規表達式,采用find方法查找資訊
    # 23和下邊的9,4都是偏移量(自己在網頁上審閱元素數即可)  
    b = html.find(']',a)
    return html[a:b]def find_imgs(page_url):
    url_open(url).decode('utf-8')
    img_addrs = []
    a = html.find('img src=')
    while a != -1:  
        b = html.find('.jpg',a,a+255)  
        #限制b的範圍
        #找不到jpg(因為存在gif的情況)即b傳回-1
        if b != -1:
            img_addrs.append(html[a+9:b+4])
        else:
            b = a + 9  
        a = html.find('img src=',b) #起始于b
    for each in img.addrs:
        print(each)       

def save_img(folder, img_addrs):
    for each in img_addrs:
        filename = each.split('/')[-1]
        #分離出最後一個‘/’後的内容作為名稱
        with open(filename,'wb') as f:
            img = url_open(each)
            f.write(img)      

繼續閱讀