0x00 前言

我们用爬虫收集到信息后,太过杂乱的话可不利于分析。假如能输出成表格的形式会更直观,有幸的是python有 xlwt 这个写表格的库(相对的有一个叫 xlrt 的读取表格的库),这就很方便了。

正巧这几天有个朋友遇到了相关的问题找我帮忙,我也趁此机会学习了一下。

0x01 使用格式

sheet.write($row, $col, $content, $Style)

注释:带 ‘$’ 代表为变量

示例

'''
在表格 0 行 3 列处 (即 1A )
以宋体加粗的格式 (前提已定义set_style函数)
写入字符串 'Hello'
'''
sheet.write(0, 3, 'Hello', set_style(u'宋体', 220, True))

0x02 一次性写入表格

这个是我最开始找到资料,也是一开始使用的方法。

首先,先定义一个设置单元格样式的函数

'''
设置单元格样式
'''
def set_style(name,height,bold=False):
    style = xlwt.XFStyle() # 初始化样式

    font = xlwt.Font() # 为样式创建字体
    font.name = name # 'Times New Roman'
    font.bold = bold
    font.colour_index = 0
    font.height = height

    style.font = font

    return style

接着,创建 工作簿sheet

def write_excel():
    f = xlwt.Workbook() # 创建工作簿
    # 创建 sheet ,可根据需要创建多个
    sheet1 = f.add_sheet('sheet1', cell_overwrite_ok=True)

写入第一行加粗作为分类的标题

    # 第一行
    row0 = ['range', 'image', 'title', 'recommend', 'author', 'times', 'price']
    for i in range(0,len(row0)):
        sheet.write(0,i,row0[i],set_style(u'宋体',220,True))

不断循环往内对应单元格写入数据

    row = 1 # 从行 2 开始写(行 1 是分类标题)
    for item in items:
        print(row)
        sheet.write(row,0,item['range'],set_style(u'宋体',220,False))
        sheet.write(row,1,item['image'],set_style(u'宋体',220,False))
        sheet.write(row,2,item['title'],set_style(u'宋体',220,False))
        sheet.write(row,3,item['recommend'],set_style(u'宋体',220,False))
        sheet.write(row,4,item['author'],set_style(u'宋体',220,False))
        sheet.write(row,5,item['times'],set_style(u'宋体',220,False))
        sheet.write(row,6,item['price'],set_style(u'宋体',220,False))
        row = row + 1

    f.save('demo1.xlsx')

至此,我们可以完成一次性的写入并保存下来

0x03 往现有表格后添加数据

前面的方法虽然能基本上解决问题,但第二次写入的时候会把前面已经填写过的单元格清空,并不能得到我想要的效果。所以后面我又去找了一下能够往现有表格后添加数据的方法。

于是,我在中间添加了一段这个代码

    # 使数据每次写入都以追加的方式,防止覆盖前面数据
    # 可注释掉此段进行尝试
    from xlrd import open_workbook
    from xlutils.copy import copy
    rb = open_workbook('demo1.xlsx')
    f = copy(rb)
    sheet = f.get_sheet(0)

同时为了行数能累积下去,我把 row 这个变量也改成了全局变量

    global row

以下是完整代码

import requests
import re
import json
import xlwt


def main(page):
    url = 'http://bang.dangdang.com/books/fivestars/1-' + str(page)
    html = request_dandan(url)
    items = parse_result(html)
    write_item_to_excel(items)


def request_dandan(url):
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.text
    except requests.RequestException:
        return None


def parse_result(html):
    pattern = re.compile('<li>.*?list_num.*?(\d+).</div>.*?<img src="(.*?)".*?class="name".*?title="(.*?)">.*?class="star">.*?class="tuijian">(.*?)</span>.*?class="publisher_info">.*?target="_blank">(.*?)</a>.*?class="biaosheng">.*?<span>(.*?)</span></div>.*?<p><span\sclass="price_n">¥(.*?)</span>.*?</li>',re.S)
    items = re.findall(pattern,html)
    for item in items:
        yield {
            'range': item[0],
            'image': item[1],
            'title': item[2],
            'recommend': item[3],
            'author': item[4],
            'times': item[5],
            'price': item[6]
        }
    return items
#    print(item)


def write_item_to_file(item):
    print('开始写入数据 ===> ' + str(item))
    with open('book.txt', 'a', encoding='UTF-8') as f:
        f.write(json.dumps(item, ensure_ascii=False) + '\n')
        f.close


def set_excel_style(name, height, bold=False):
    style = xlwt.XFStyle()

    font = xlwt.Font()
    font.name = name
    font.bold = bold
    font.colour_index = 0
    font.height = height

    style.font = font
    return style


def write_item_to_excel(items):
    f = xlwt.Workbook()
    sheet = f.add_sheet('sheet1', cell_overwrite_ok=True)

    # 第一行
    row0 = ['range', 'image', 'title', 'recommend', 'author', 'times', 'price']
    for i in range(0,len(row0)):
        sheet.write(0,i,row0[i],set_excel_style(u'宋体',220,True))

    # 数据

    # 使数据每次写入都以追加的方式,防止覆盖前面数据
    # 可注释掉此段进行尝试
    from xlrd import open_workbook
    from xlutils.copy import copy
    rb = open_workbook('demo1.xlsx')
    f = copy(rb)
    sheet = f.get_sheet(0)

    # 26 页,每页 20 本书
    # 使用全局变量 row 记录写到第几行
    global row

    for item in items:
        print(row)
        sheet.write(row,0,item['range'],set_excel_style(u'宋体',220,False))
        sheet.write(row,1,item['image'],set_excel_style(u'宋体',220,False))
        sheet.write(row,2,item['title'],set_excel_style(u'宋体',220,False))
        sheet.write(row,3,item['recommend'],set_excel_style(u'宋体',220,False))
        sheet.write(row,4,item['author'],set_excel_style(u'宋体',220,False))
        sheet.write(row,5,item['times'],set_excel_style(u'宋体',220,False))
        sheet.write(row,6,item['price'],set_excel_style(u'宋体',220,False))
        row = row + 1

    f.save('demo1.xlsx')

if __name__ == '__main__':
    global row
    row = 1 # 表格第二行开始写
    for i in range(1, 26):
        main(i)

0x04 结尾

end.

分类: Python

发表评论

电子邮件地址不会被公开。 必填项已用*标注