【Python數據分析】Python3操作Excel(二) 一些問題的解決與優化

来源:http://www.cnblogs.com/whatbeg/archive/2016/03/28/5327937.html
-Advertisement-
Play Games

繼上一篇【Python數據分析】Python3操作Excel-以豆瓣圖書Top250為例 對豆瓣圖書Top250進行爬取以後,鑒於還有一些問題沒有解決,所以進行了進一步的交流討論,這期間得到了一隻尼瑪的幫助與啟發,十分感謝! 上次存在的問題如下: 1.寫入不能繼續的問題 2.在Python IDLE ...


    繼上一篇【Python數據分析】Python3操作Excel-以豆瓣圖書Top250為例 對豆瓣圖書Top250進行爬取以後,鑒於還有一些問題沒有解決,所以進行了進一步的交流討論,這期間得到了一隻尼瑪的幫助與啟發,十分感謝!

    上次存在的問題如下:

    1.寫入不能繼續的問題

    2.在Python IDLE中明明輸出正確的結果,寫到excel中就亂碼了。

    上述兩個問題促使我改換excel處理模塊,因為據說xlwt只支持到Excel 2003,很有可能會出問題。

    雖然“一隻尼瑪”給了一個Validate函數,可是那是針對去除Windows下文件名中非法字元的函數,跟寫入excel亂碼沒有關係,所以還是考慮更換模塊。

更換xlsxwriter模塊

    這次我改成xlsxwriter這個模塊,https://pypi.python.org/pypi/XlsxWriter. 同樣可以pip3 install xlsxwriter,自動下載安裝,簡便易行。一些用法樣例:

import xlsxwriter

# Create an new Excel file and add a worksheet.
workbook = xlsxwriter.Workbook('demo.xlsx')
worksheet = workbook.add_worksheet()

# Widen the first column to make the text clearer.
worksheet.set_column('A:A', 20)

# Add a bold format to use to highlight cells.
bold = workbook.add_format({'bold': True})

# Write some simple text.
worksheet.write('A1', 'Hello')

# Text with formatting.
worksheet.write('A2', 'World', bold)

# Write some numbers, with row/column notation.
worksheet.write(2, 0, 123)
worksheet.write(3, 0, 123.456)

# Insert an image.
worksheet.insert_image('B5', 'logo.png')

workbook.close()

果斷更換寫入excel的代碼。效果如下:

果然鼻子是鼻子臉是臉,該是鏈接就是鏈接,不管什麼字元都能寫,畢竟unicode。

所以說,選對模塊很重要選對模塊很重要選對模塊很重要!(重說三)

如果要爬的內容不是很公正標準的字元串或數字的話,我是不會用xlwt啦。

這裡有4中Python寫入excel的模塊對比:http://ju.outofmemory.cn/entry/56671

我截了一個對比圖如下,具體可以看上面那篇文章,非常詳細!

順藤摸瓜

這個既然如此順暢,還可以寫入圖片,那我們何不試試看呢?

目標:把圖片鏈接那一列的內容換成真正的圖片!

其實很簡單,因為我們之前已經有了圖片的存儲路徑,把它插入到裡面就可以了。

    the_img = "I:\\douban\\image\\"+bookName+".jpg"
    writelist=[i+j,bookName,nickname,rating,nums,the_img,bookurl,notion,tag]
    for k in range(0,9):
        if k == 5:
            worksheet.insert_image(i+j,k,the_img)
        else:
            worksheet.write(i+j,k,writelist[k])

出來是這樣的效果,顯然不美觀,那我們應該適當調整一些每行的高度,以及讓他們居中試試看:

查閱xlsxwriter文檔可知,可以這麼設置行列寬度和居中:(當然,這些操作在excel中可以直接做,而且可能會比寫代碼更快,但是我倒是想更多試試這個模塊)

format = workbookx.add_format()
format.set_align('justify')
format.set_align('center')
format.set_align('vjustify')
format.set_align('vcenter')
format.set_text_wrap()

worksheet.set_row(0,12,format)
for i in range(1,251):
    worksheet.set_row(i,70)
worksheet.set_column('A:A',3,format)
worksheet.set_column('B:C',17,format)
worksheet.set_column('D:D',4,format)
worksheet.set_column('E:E',7,format)
worksheet.set_column('F:F',10,format)
worksheet.set_column('G:G',19,format)
worksheet.set_column('H:I',40,format)

至此完成了excel的寫入,只不過設置格式這塊實在繁雜,得不斷調試距離,大小,所以在excel裡面做會簡單些。

最終代碼:

# -*- coding:utf-8 -*-
import requests
import re
import xlwt
import xlsxwriter
from bs4 import BeautifulSoup
from datetime import datetime
import codecs

now = datetime.now()             #開始計時
print(now)

def validate(title):                        #from nima
    rstr = r"[\/\\\:\*\?\"\<\>\|]"          # '/\:*?"<>|-'
    new_title = re.sub(rstr, "", title)
    return new_title

txtfile = codecs.open("top2501.txt",'w','utf-8')
url = "http://book.douban.com/top250?"

header = { "User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.13 Safari/537.36",
           "Referer": "http://book.douban.com/"
           }

image_dir = "I:\\douban\\image\\"
#下載圖片
def download_img(imageurl,imageName = "xxx.jpg"):
    rsp = requests.get(imageurl, stream=True)
    image = rsp.content
    path = image_dir + imageName +'.jpg'
    #print(path)
    with open(path,'wb') as file:
        file.write(image)

#建立Excel
workbookx = xlsxwriter.Workbook('I:\\douban\\btop250.xlsx')
worksheet = workbookx.add_worksheet()
format = workbookx.add_format()
format.set_align('justify')
format.set_align('center')
format.set_align('vjustify')
format.set_align('vcenter')
format.set_text_wrap()

worksheet.set_row(0,12,format)
for i in range(1,251):
    worksheet.set_row(i,70)
worksheet.set_column('A:A',3,format)
worksheet.set_column('B:C',17,format)
worksheet.set_column('D:D',4,format)
worksheet.set_column('E:E',7,format)
worksheet.set_column('F:F',10,format)
worksheet.set_column('G:G',19,format)
worksheet.set_column('H:I',40,format)

item = ['書名','別稱','評分','評價人數','封面','圖書鏈接','出版信息','標簽']
for i in range(1,9):
    worksheet.write(0,i,item[i-1])
        
s = requests.Session()      #建立會話
s.get(url,headers=header)

for i in range(0,250,25):  
    geturl = url + "/start=" + str(i)                     #要獲取的頁面地址
    print("Now to get " + geturl)
    postData = {"start":i}                                #post數據
    res = s.post(url,data = postData,headers = header)    #post
    soup = BeautifulSoup(res.content.decode(),"html.parser")       #BeautifulSoup解析
    table = soup.findAll('table',{"width":"100%"})        #找到所有圖書信息的table
    sz = len(table)                                       #sz = 25,每頁列出25篇文章
    for j in range(1,sz+1):                               #j = 1~25
        sp = BeautifulSoup(str(table[j-1]),"html.parser") #解析每本圖書的信息

        imageurl = sp.img['src']                          #找圖片鏈接
        bookurl = sp.a['href']                            #找圖書鏈接
        bookName = sp.div.a['title']
        nickname = sp.div.span                            #找別名
        if(nickname):                                     #如果有別名則存儲別名否則存’無‘
            nickname = nickname.string.strip()
        else:
            nickname = ""
        
        notion = str(sp.find('p',{"class":"pl"}).string)   #抓取出版信息,註意裡面的.string還不是真的str類型
        rating = str(sp.find('span',{"class":"rating_nums"}).string)    #抓取平分數據
        nums = sp.find('span',{"class":"pl"}).string                    #抓取評分人數
        nums = nums.replace('(','').replace(')','').replace('\n','').strip()
        nums = re.findall('(\d+)人評價',nums)[0]
        download_img(imageurl,bookName)                     #下載圖片
        book = requests.get(bookurl)                        #打開該圖書的網頁
        sp3 = BeautifulSoup(book.content,"html.parser")     #解析
        taglist = sp3.find_all('a',{"class":"  tag"})       #找標簽信息
        tag = ""
        lis = []
        for tagurl in taglist:
            sp4 = BeautifulSoup(str(tagurl),"html.parser")  #解析每個標簽
            lis.append(str(sp4.a.string))
        
        tag = ','.join(lis)        #加逗號
        the_img = "I:\\douban\\image\\"+bookName+".jpg"
        writelist=[i+j,bookName,nickname,rating,nums,the_img,bookurl,notion,tag]
        for k in range(0,9):
            if k == 5:
                worksheet.insert_image(i+j,k,the_img)
            else:
                worksheet.write(i+j,k,writelist[k])
            txtfile.write(str(writelist[k]))
            txtfile.write('\t')
        txtfile.write(u'\r\n')

end = datetime.now()    #結束計時
print(end)
print("程式耗時: " + str(end-now))
txtfile.close()
workbookx.close()
View Code

運行結果如下:

2016-03-28 11:40:50.525635
Now to get http://book.douban.com/top250?/start=0
Now to get http://book.douban.com/top250?/start=25
Now to get http://book.douban.com/top250?/start=50
Now to get http://book.douban.com/top250?/start=75
Now to get http://book.douban.com/top250?/start=100
Now to get http://book.douban.com/top250?/start=125
Now to get http://book.douban.com/top250?/start=150
Now to get http://book.douban.com/top250?/start=175
Now to get http://book.douban.com/top250?/start=200
Now to get http://book.douban.com/top250?/start=225
2016-03-28 11:48:14.946184
程式耗時: 0:07:24.420549

順利爬完250本書。此次爬取行動就正確性來說已告完成!

本次耗時7分24秒,還是顯得太慢了。下一步就應該是如何在提高效率上面下功夫了。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在MVC中,Filter也是可以擴展的。在此,本人對Filter的理解就是AOP,不知道各位大俠,有什麼高的見解,呵呵。。。 首先MVC四大過濾神器IAuthorizationFilter,IActionFilter,IResultFilter,IExceptionFilter。 在此之前,我們先安 ...
  • Session.Abandon();//清除全部Session//清除某個SessionSession["UserName"] = null;Session.Remove("UserName"); Session["aa"]=變數名; //賦值 ...
  • Julia中文教程資源.txt 2016年3月28日 05:18:32 codegay 本文更新在這裡: https://github.com/FGFW/julia science and technology 官方的資料總是少不了需要自己去看的. julia 英文手冊 http://docs.ju ...
  • 繼續上一章所講,上一章我們最後面說道,雖然這個是很小的程式,但還有好幾個要優化的地方。先複製一下老的view.py代碼。 其中驗證token的方法,已經重疊了,python教我們,永遠不要重覆自己的代碼,這是很醜陋的行為。今天我們把它換成一個裝飾器,然後再把redis調整一下,看看代碼會不會簡潔很多 ...
  • 最近折騰微信掃碼支付,看了微信官方文檔,找了很多網頁,發現和文檔/demo不匹配,現在自己算是弄出來了(文件名稱有所更改),貼出來分享一下 一.將有用的官方lib文件和使用的相關文件放置到vendor當中 二.調用同一支付介面 WechatController ...
  • 原址:http://blog.chedushi.com/archives/7258 最近在用 xlrd 寫一個題庫自動導出的程式,但碰到一個比較 ugly 的問題。 程式要求是將 xls 文件中的數據導出成文本,但 xlrd 在讀取數據時,會將 xls 單元格中所有可能是數字的數據都自動轉換成 py ...
  • 代碼: 中間就遇見一個問題很讓我糾結,就是xlrd 在讀取數據時,會將 xls 單元格中所有可能是數字的數據都自動轉換成 python 的 float。這時候,我們通過 str(cell.value) 會得到 12.0 (假設 cell.value = 12.0)。 解決辦法:比如我的a=1,那麼x ...
  • 2015老男孩Python培訓第八期視頻教程,希望您通過本教程的學習,能學會常用方法和技巧。教程從基礎知識開始講解一直到後期的案例實戰,完全零基礎學習,從初學者的角度探討分析問題,循序漸進由易到難,確保每一位初學者都能融會貫通。從零基礎到開發的大神,您只要兩個字——堅持!屌絲逆襲模式已經開啟,各位小 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...