继上一篇【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()

运行结果如下:

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秒,还是显得太慢了。下一步就应该是如何在提高效率上面下功夫了。

【Python数据分析】Python3操作Excel(二) 一些问题的解决与优化的更多相关文章

  1. 转 Python - openpyxl 读写操作Excel

    Python - openpyxl 读写操作Excel   openpyxl特点   openpyxl(可读写excel表)专门处理Excel2007及以上版本产生的xlsx文件,xls和xlsx之间 ...

  2. python通过openpyxl操作excel

    python 对Excel操作常用的主要有xlwt.xlrd.openpyxl ,前者xlwt主要适合于对后缀为xls比较进行写入,而openpyxl主要是针对于Excel 2007 以上版本进行操作 ...

  3. 09 python学习笔记-操作excel(九)

    python操作excel使用xlrd.xlwt和xlutils模块,xlrd模块是读取excel的,xlwt模块是写excel的,xlutils是用来修改excel的.这几个模块可以使用pip安装, ...

  4. python用openpyxl操作excel

    python操作excel方法 1)自身有Win32 COM操作office但讲不清楚,可能不支持夸平台,linux是否能用不清楚,其他有专业处理模块,如下 2)xlrd:(读excel)表,xlrd ...

  5. python3 操作excel表

    python操作excel主要用到xlrd和xlwt这两个库,即xlrd是读excel,xlwt是写excel的库可从这里下载https://pypi.python.org/pypi.下面分别记录py ...

  6. 用python库openpyxl操作excel,从源excel表中提取信息复制到目标excel表中

    现代生活中,我们很难不与excel表打交道,excel表有着易学易用的优点,只是当表中数据量很大,我们又需要从其他表册中复制粘贴一些数据(比如身份证号)的时候,我们会越来越倦怠,毕竟我们不是机器,没法 ...

  7. Python - openpyxl 读写操作Excel

    openpyxl特点   openpyxl(可读写excel表)专门处理Excel2007及以上版本产生的xlsx文件,xls和xlsx之间转换容易 注意:如果文字编码是“gb2312” 读取后就会显 ...

  8. python使用xlrd操作Excel文件

    一.xlrd读取Excel文件 用xlrd进行读取比较方便,流程和平常手动操作Excel一样,打开工作簿(Workbook),选择工作表(sheets),然后操作单元格(cell). 例子:要打开当前 ...

  9. python使用xlrd 操作Excel读写

    此文章非本人 一.安装xlrd模块 到python官网下载http://pypi.python.org/pypi/xlrd模块安装,前提是已经安装了python 环境. 二.使用介绍 1.导入模块 i ...

随机推荐

  1. 关于xamarin.forms在MVVM情况下如何DisplayActionSheet

    最近一直在研究Xmarin.forms,碰到了一个棘手的问题,就是在MVVM的情况下如何在ViewModel中去使用DisplayActionSheet,然而我使用的是XAML模式,也就是说,只有在后 ...

  2. Debian 7 安装配置总结

    最近几天折腾了一下Debian 7 (gnome桌面DVD版,KDE桌面CD版最后会提到),总的来说收获还是挺大的,对比以前使用ubuntu,debian 7给我的感觉像是一个新生婴儿,不带多余的花俏 ...

  3. 在PHP语言中使用JSON和将json还原成数组

    在之前我写过php返回json数据简单实例,刚刚上网,突然发现一篇文章,也是介绍json的,还挺详细,值得参考.内容如下 从5.2版本开始,PHP原生提供json_encode()和json_deco ...

  4. sqlserver性能调优第一步

    相信不少的朋友,无论是做开发.架构的,还是DBA等,都经常听说“调优”这个词.说起“调优”,可能会让很多技术人员心头激情澎湃,也可能会让很多人感觉苦恼,不知道如何入手.当然,也有很多人对此不屑一顾,因 ...

  5. C# new关键字

    在 C# 中,new 关键字可用作运算符.修饰符或约束 1.new 运算符:用于创建对象和调用构造函数.2.new 修饰符:用作修饰符时,new 关键字可以显式隐藏从基类继承的成员.3.new 约束: ...

  6. CSS3与页面布局学习笔记(四)——页面布局大全(负边距、双飞翼、多栏、弹性、流式、瀑布流、响应式布局)

    一.负边距与浮动布局 1.1.负边距 所谓的负边距就是margin取负值的情况,如margin:-100px,margin:-100%.当一个元素与另一个元素margin取负值时将拉近距离.常见的功能 ...

  7. 字体属性设置(一):谷歌浏览器12px以下字体的显示;方法和原理

    前言: chrome 谷歌浏览器默认的字体大小为16px:可以通过设置font-size来设置字体大小但是当设置到12px以下的时候字体大小不再改变:对于想设置其他大小的字体就很头疼,本文参考网上的方 ...

  8. JavaScript中this指向的简单理解

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  9. jquery获取关于宽度和高度的尺寸问题

    作者原创,转载请出名出处! console.log("可视区高度:"+$(window).height()); console.log("可视区宽度:"+$(w ...

  10. Oracle a Parameter with multi value

     备注:此两种方案,都因为oracle内部字符函数的参数长度4000限制.另外,个人测试,性能不如”将数据插入物理表再JOIN查询“或”每1000次ID做一次IN查询“的总的运行速度. 即ID的个数越 ...