Post請求data參數構造及巧用js腳本顯示爬蟲進度

  小爬最近隨着對python中字符串、json等理解進一步加深,發現先前我隨筆中提到的data構造和傳參方法略複雜,本來有更簡單的方法,Mark以下。html

先前小爬我使用的requests.post請求中data構造的代碼以下:python

data_search={
    'page':1,
    'rows':15,
    'condition':
    """[\ {"column":"BPM_DEF_NAME","exp":"like","value":""},\ {"column":"DELETE_STATUS","exp":"=","value":0},\ {"column":"TO_CHAR(TO_DATE(CREATE_DATE,'YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD')","exp":">=","value":"YYYY-MM-DD"},\ {"column":"TO_CHAR(TO_DATE(CREATE_DATE,'YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD')","exp":"<=","value":"YYYY-MM-DD"},\ {"column":"CHECK_TYPE","exp":"like","value":"2"},\ {"column":"LOCKED_STATUS","exp":"=","value":0},\ {"column":"DELETE_STATUS","orderType":"default","orderKey":"","direction":"ASC"}\ ]""",   #考慮到該字段已經有單引號、雙引號,因此只能用三引號來包住這部分表明字符串
    'additionalParams':'{}'
}
data_search_condition=json.loads(data_search['condition'])    #將字符串轉爲列表,方便更新列表(列表中每一個元素都是一個單個字典)元素
#刷新字典
data_search_condition[0]['value']=businessName
data_search_condition[2]['value']=str(startDate)
data_search_condition[3]['value']=str(endDate)
data_search['condition']=json.dumps(data_search_condition)  #將列表從新轉回字符串,做爲data_search字典中鍵「condition」對應的「value」,而後更新字典

  該方法主要經過json的dumps、loads方法來完成「字符串→字典列表→列表或字典值更新→字典、列表轉回str字符串」,代碼複雜且可讀性差。編程

後細想下,上面的代碼中紅色部分(即data_search['condition']對應值)看上去,既有單引號、雙引號、也有三引號,但其做爲總體,本質上就是三引號包着的字符串,因此原則上它可使用字符串的傳參方法來載入變量,因而代碼能夠改成:json

data_search={
    'page':1,
    'rows':15,
    'condition':
    """[\
        {"column":"BPM_DEF_NAME","exp":"like","value":"%s"},\
        {"column":"DELETE_STATUS","exp":"=","value":0},\
        {"column":"TO_CHAR(TO_DATE(CREATE_DATE,'YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD')","exp":">=","value":"%s"},\
        {"column":"TO_CHAR(TO_DATE(CREATE_DATE,'YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD')","exp":"<=","value":"%s"},\
        {"column":"CHECK_TYPE","exp":"like","value":"2"},\
        {"column":"LOCKED_STATUS","exp":"=","value":0},\
        {"column":"DELETE_STATUS","orderType":"default","orderKey":"","direction":"ASC"}\
    ]"""%(businessName,str(startDate),str(endDate)),   
    'additionalParams':'{}'
}

再次證實編程達到目的的方法遠不止一次,可是各類方法之間在可讀性、性能、複雜度上卻存有差異。小爬也是告誡本身,永遠要本着化繁爲簡的思想去編程。瀏覽器

 

  另外,小爬我給部門同事製做了一個內網數據爬取到excel的小工具,其中須要用到python中網頁附件的下載、excel存儲、txt存儲,excel超連接生成等功能,通過摸索,終於搞定!服務器

主要思路是,post請求(參數:「編號」)獲得json文件,將json中主要字段存儲到列表中,取出「附件」字段值,再去表單主頁面源碼中看「附件」的url,進而構造出對應的附件url地址。略去不表,下面重點講如何下載附件、判斷服務器中附件的名稱和文件後綴等。session

判斷文件名和後綴的代碼以下:app

#定義fileType方法,獲得文件類型
def get_fileType(response):
    #fileType=response.headers['Content-Type']  #  image/jpeg;charset=UTF-8    #Content-Type: application/pdf;charset=UTF-8
    fileType=response.headers['Content-Disposition']  #Content-Disposition: attachment; filename=%E6%9C%96%B0%E8%90%A5%E4%B8%9A%E6%89%A7%E7%85%A7.pdf
    #fileType=re.search(".*?/(.*?);.*?",fileType)
    fileType=os.path.splitext(fileType)[-1][1:].lower()
    return fileType

能夠看到咱們請求附件對應的url地址時,服務器返回的Response Headers頭文件中,Content-Disposition和Content-Type字段能看到文件名和後綴,須要注意的是,實際使用時,小爬發現Content-Type字段並不老是存在,此時可能須要使用try……except方法對兩個字段進行嘗試,提高程序的容錯能力。工具

下載附件、寫入excel並生成超連接用到的示例代碼以下:post

response=requests.session().get(url)
fileType=get_fileType(response)
with open(".\\Attachment\\附件.%s"%(fileType), "wb") as code:
  code.write(response.content) #下載附件
sheet['A1'].hyperlink = ".\\Attachment\\附件.%s"%(fileType)

 

 

  小爬再說說製做簡易進度條這件事兒:若是咱們要製做很酷炫、多功能的GUI用戶界面,固然首選pyqt五、wxPython、tkinter等著名GUI庫。可是筆者若是隻是想把腳本封裝爲exe,給通常用戶使用,只是須要一個簡單的進度提醒,若是對美觀等沒有特別的要求,則用Selenium+js的方法更容易實現。

小爬個人爬蟲工具首先用selenium的driver方法打開了瀏覽器,以後的爬取過程,都是儘量調用requests方法,此時網頁並不會跟着刷新。原始的網頁左上角以下圖所示:

小爬經過selenium載入js的方法,能夠更改「抽查記錄信息」這個div標籤在本地瀏覽器顯示的文本爲「我想要輸出的進度信息」,且不會對服務器形成任何變化。巧妙達到製做進度的要求。

該div的html信息,能夠經過查詢網頁源碼獲得:「<div class="haf-form-title">抽查記錄信息</div>」,那麼讓這個頁面元素對應的文本更改須要的代碼很簡單,先用querySelector方法定位,再更改attr屬性,示例代碼以下:

driver.execute_script('document.querySelector("div.haf-form-title").textContent="%s 已完成%d行數據."'%(name,Num)) 

是的,這行代碼足夠顯示基本的進度了,你能夠傳入更多參數來顯示總數、實時計數和百分比等,靈活運用該方法便可。實際效果以下:

 

                                            方法不少,咱們只要作到「活學活用」便可!

相關文章
相關標籤/搜索