定時從某網站爬取壓縮包


一、緣 起

要買房,但是大西安現在可謂是一房難求,大家都爭先恐后地排隊交資料、搖號。截止到現在,筆者已經參與過6個樓盤的搖號/選房,但種種原因,依然沒買到合適的房子,無奈,一首 涼~ 涼~ 回盪在心~
價格公示,每次都會在買房群里熱議,因為看到新公布的價格就意味着有更多房源即將開盤,大家買房的熱情又會被重新點燃~
閃念,有一次的一個念想,如果能實時監控物價局官網、自動下載壓縮包並提醒我,這樣豈不快哉,於是之前了解的一點點網絡爬蟲就派上用場~
於是,開干!

二、思 路

首先,用selenium(PhantomJS)爬取網站的下載鏈接
然后,用Python request模塊的urlretrieve() 方法下載壓縮包
接着,用Python zipfile模塊的extractall()方法解壓
最后,定時運行腳本,有下載更新時候彈出提示

三、說 明

軟件模塊

  1. Python3.6 + PhantomJS + .vbs腳本 + .bat腳本
  2. PhantomJS:因為要做實時監控,所以爬取網頁鏈接必須在后台運行, 而PhantomJS正可謂是無界面版的Selenium僅個人通俗的理解,對PhantomJS更准確的說明和用法請自行百度
  3. 定時運行,首先想到的是Jenkins持續集成,但鑒於筆者對Jenkins不甚熟悉,並且目前也只想基於Windows運行,故選擇了較為簡單的方法,即在Windows下添加定時任務,具體方法請自行百度,很簡單
  4. 因為.bat批處理腳本調用Python腳本每次都會打開cmd命令框,所以用.vbs腳本來調用Python腳本
  5. 更新提醒,可以發送郵件,但是筆者用了最簡單的方法,即有更新時候調用openFolder.bat批處理腳本自動打開house_prices文件夾

四、實 現

先上兩張物價局官網
一級下載頁面
二級下載頁面

  • downloadZip.py
  1. 主程序分為兩部分,get_url()函數用於從一級下載頁面爬取鏈接,初次運行腳本會將一級下載頁面首頁的所有鏈接爬取下來並寫入txt,后面如果再有更新,只會將最新的一級下載頁面鏈接追加到txt里面,當get_url()函數返回值為0,表示無更新,返回值為1表示初次運行腳本,否則表示有部分更新
......
from selenium import webdriver


def get_url():

    """
    獲取url並寫入txt
    :return:download_flag 
    """
    # 頁面為iframe框架
    driver.switch_to.frame('iframecenter')
    date_list = driver.find_elements_by_xpath('.//*[@id="tablelist"]/tbody/tr/td[3]/span')
    fw = open(cur_path + "/house_prices/url_list.txt", 'a')
    fr = open(cur_path + "/house_prices/url_list.txt", 'r')
    download_flag = 0
    # print(fr.readlines())
    f_list = fr.readlines()
    # print(f_list)
    if len(f_list) == 0:
        for i in reversed(range(len(date_list))):   # 寫入順序為時間逆序
            fw.writelines(driver.find_elements_by_id('linkId')[i].get_attribute('href'))
            fw.write('\n')
        download_flag = 1
    else:
        # 獲取txt文件里面最新的一級下載頁面鏈接的trid
        f_latest_num = int(f_list[-1].split('=')[1])
        for i in reversed(range(0, 5)):   
        # 獲取當前網站最新的5條一級下載頁面鏈接及trid,如果當前網站的trid > txt最新的trid,則追加到txt
            latest_url = driver.find_elements_by_id('linkId')[i].get_attribute('href')
            latest_url_num = int(latest_url.split('=')[1])
            if f_latest_num < latest_url_num:
                fw.writelines(latest_url)
                fw.write('\n')
                download_flag = download_flag + 1

    fw.close()
    return download_flag
  1. 主程序第二部分,download_zip()函數根據get_url()函數返回值判斷,是否要進入二級下載頁面下載壓縮包,並且只有在有下載發生時候才調用openFolder.bat打開house_prices文件夾,做以提示,否則不執行下載函數不打開文件夾
......
from urllib import request
import zipfile
import os
......
def download_zip():

    """
    從txt中讀取url並下載zip
    :return:
    """
    flag = get_url()
    if flag == 1:
        fr = open(cur_path + "/house_prices/url_list.txt", 'r')
        all_lines = fr.readlines()
        for line_url in all_lines:
            driver.get(line_url)
            driver.implicitly_wait(15)
            # 頁面為iframe框架
            driver.switch_to.frame('showconent1')
            download_url = driver.find_element_by_partial_link_text('商品住房價格')
            download_url = download_url.get_attribute('href')
            zipname = cur_path + '/house_prices/' + download_url.split('/')[6]
            filename = zipname.split('.')[0]
            request.urlretrieve(download_url, zipname)
            # 解壓並刪除壓縮包
            try:
                with zipfile.ZipFile(zipname) as zfile:
                    zfile.extractall(path=filename)
                if os.path.exists(zipname):
                    os.remove(zipname)
            except zipfile.BadZipFile as e:
                print(filename + " is a bad zip file ,please check!")

        # 有更新數據打開文件夾
        os.system(cur_path + "/openFolder.bat")

    elif flag != 1 and flag != 0:
        fr = open(cur_path + "/house_prices/url_list.txt", 'r')
        all_lines = fr.readlines()
        for line_url in range(flag):
            driver.get(all_lines[-line_url-1])
            driver.implicitly_wait(15)
            driver.switch_to.frame('showconent1')
            # download_url = driver.find_element_by_xpath('/html/body/div/div[3]/p[3]/a')
            download_url = driver.find_element_by_partial_link_text('商品住房價格')
            download_url = download_url.get_attribute('href')
            zipname = cur_path + '/house_prices/' + download_url.split('/')[6]
            filename = zipname.split('.')[0]
            request.urlretrieve(download_url, zipname)
            # 解壓並刪除壓縮包
            try:
                with zipfile.ZipFile(zipname) as zfile:
                    zfile.extractall(path=filename)
                if os.path.exists(zipname):
                    os.remove(zipname)
            except zipfile.BadZipFile as e:
                print(filename + " is a bad zip file ,please check!")

        # 有更新數據打開文件夾
        os.system(cur_path + "/openFolder.bat")
  • autoDownloadZip.vbs
    用於調用Python腳本且不會打開cmd命令框
currentpath = createobject("Scripting.FileSystemObject").GetFile(Wscript.ScriptFullName).ParentFolder.Path
createobject("wscript.shell").run currentpath + "\downloadZip.py",0

添加定時任務腳本
設置定時任務

  • openFolder.bat
    用於打開house_prices文件夾
start %~dp0\house_prices

五、最 后

Git地址:https://gitee.com/freedomlidi/autoDownloadZip.git

OK!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM