Python数据分析----Python3操作Excel-以豆瓣图书Top250为例

本文介绍如何使用Python3爬虫抓取豆瓣图书Top250的数据,并利用xlwt模块存储至Excel文件,同时下载封面图片。过程中解决了图片路径编码及Excel写入问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文利用Python3爬虫抓取豆瓣图书Top250,并利用xlwt模块将其存储至excel文件,图片下载到相应目录。旨在进行更多的爬虫实践练习以及模块学习。

工具

1.Python 3.5

2.BeautifulSoup、xlwt模块

开始动手

首先查看目标网页的url: https://book.douban.com/top250?start=0, 然后我尝试了在代码里直接通过字符串连接仅改变”start=“后面的数字的方法来遍历所有的250/25 = 10页内容,但是后来发现不行,那样的话出来的永远是第一页,于是通过浏览器的F12开发者工具检查,发现start是要post上去的,如下图:

(图1)

所以建立一个postData的dict:

1

postData = {"start": i}    #i为0,25,...225

每次将其post上去即可解决返回都是第一页的问题。

分析网页可知,一本书的罗列信息以及要爬取的点如下图:

(图2)

从上到下需要爬取的信息有:

1.图书链接地址

2.封面图片链接    我到时候会将此链接打开,下载图片到本地 (download_img函数)

3.书名    要注意的是这里书名取title的内容而不去a标签中的string信息,因为string信息可能包含诸如空格、换行符之类的字符,给处理造成麻烦,直接取title格式正确且无需额外处理。

4.别名    这里主要是副标题或者是外文名,有的书没有这项,那么我们就写入一个“无”,千万不可以写入一个空串,否则的话会出现故障,我下面会提到。

5.出版信息  如作者、译者、出版社、出版年份、价格, 这也是重要信息之一,否则有多本书名字一致可能会无法分辨

6.评分

7.评价人数

除此之外,我还爬取一个“标签”信息,它在图书链接打开之后的网页中,找到它的位置如下:

(图3)

爬到标签以后将它们用逗号连接起来作为标签值。

好了,既然明确了要爬的指标,以及了解了网页结构以及指标所在的html中的位置,那么就可以写出如下代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

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,"html.parser")       #BeautifulSoup解析

table = soup.findAll('table',{"width":"100%"})        #找到所有图书信息的table

sz = len(table)                                       #sz = 25,每页列出25篇文章

for in range(1,sz+1):                               #j = 1~25

    sp = BeautifulSoup(str(table[j-1]),"html.parser"#解析每本图书的信息

    #print(sp.div)

    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 = "None"

     

    #print(type(imageurl),imageurl)

    #print(type(bookurl),bookurl)

    #print(type(bookName),bookName)

    #print(type(nickname),nickname)

     

    notion = str(sp.find('p',{"class":"pl"}).string)   #抓取出版信息,注意里面的.string还不是真的str类型

    #print(type(notion),notion)

    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]

    #print(type(rating),rating)

    #print(type(nums),nums)

    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)        #加逗号

    if tag == "":              #如果标签为空,置"无"

        tag = "None"

通过xlwt模块存入xls文件及其问题

爬取下来了以后当然要考虑存储,这时我想试试把它存到Excel文件(.xls)中,于是搜得python操作excel可以使用xlwt,xlrd模块,虽然他们暂时只支持到excel2003,但是足够了。xlwt为Python生成.xls文件的模块,而xlrd为读取的。由于我想的是直接生成xls文件,不需用到xlrd,所以先安装xlwt。

直接进入Python目录使用如下命令即可安装xlwt:

1

pip3 install xlwt

安装完后写出操作代码,这里同时也写入txt文件,方便比较:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#建立Excel

workbook = xlwt.Workbook(encoding='utf-8')

sheet = workbook.add_sheet('book_top250',cell_overwrite_ok=True)

item = ['书名','别称','评分','评价人数','封面','图书链接','出版信息','标签']

for in range(1,9):

    sheet.write(0,i,item[i-1])

 

...

    for in range(1,sz+1):

        ...

        writelist = [i+j,bookName,nickname,float(rating),int(nums),"I:\\douban\\image\\"+bookName+".jpg",bookurl,notion,tag]

        for in range(0,9):

            sheet.write(i+j,k,writelist[k])

            txtfile.write(str(writelist[k]))

            txtfile.write('\t')

        txtfile.write(u'\r\n')

         

    workbook.save("I:\\douban\\booktop250.xls")<br>...

满以为这样就可以了,但是还是出现了一些错误。

比如曾经出现了写着写着就写不下去了的情况(以下并非以上代码产生的结果):

(图4)

这时我把不是str的都改成str了,不该str的尽量用数字(int,float),然后又遇到了下面的情况:

(图5)

写到第64项又写不下去了,但是那些int,float都写完了,‘无’也是断断续续显示几个,我想,既然找不到问题,那么慢慢套吧。首先极大可能是中文编码的问题,因为我把一些可以不为str类型的都赋成非str类型以后都正确地显示了,而且上图中的显示在图片路径名那里断了,所以我让那一列都不显示,居然,成功了!

(图6)

如图,除了不显示的那一列,其它完全正常,可以断定就是下面这里出现的错误:

1

writelist=[i+j,bookName,nickname,float(rating),int(nums),"I:\\douban\\image\\"+bookName+".jpg",bookurl,notion,tag]

我的图片路径那里是直接字符串拼接而成的,所以可能会有编码的错误。那么稍微改一下试试:

1

2

imgpath = str("I:\\douban\\image\\"+bookName+".jpg");

writelist=[i+j,bookName,nickname,float(rating),int(nums),imgpath,bookurl,notion,tag]

好吧,还是不行,还是出现图5的问题,但是打印在Python IDLE里面又都是正确的。

既然如此,把图片链接全部改成一样的英文试一下:

1

2

imgpath = str("I:\\douban\\image\\"+"a"+".jpg")

writelist=[i+j,bookName,nickname,float(rating),int(nums),imgpath,bookurl,notion,tag]

 又是正确的:('无'已改为'None')

(图7)

所以说,还是图片路径的问题,那我们索性将图片路径那列换成图片链接,采取消极应对方法,反正这项是图片链接还是图片路径无关紧要,反正图片路径里面有图片就可以了。此外我还加了一个计时的代码,计算总爬取时间,因为我觉得这样干爬太慢了,没有个将近10分钟完不成,考虑利用多线程去爬,这里先记录一下时间以观后效。然后发现还是不行!现在成了只要imageurl固定(中文也行),就能够顺利输出到xls中,否则就不行。很诡异。于是我又尝试了缩短imageurl,实验得知,当取imageurl[:-6]时是可以的,但imageurl[:-5]就不行了。后面又干脆不写入imageurl这一列,可以,不写入别名或者不写入图书链接都是正常的,但是不写入标号就不行。至今仍不得解。初步猜测莫非是写入的字符数受限制了?还得靠更多的实验才能确定。而且也说不定就是Windows下的编码问题,这又得靠在Linux下进行实验判断。所以要做的事情还很多,这里先把正确的绝大部分工作做了再说。

于是干脆不要图书地址一列,最后得出如下最终代码:

 View Code

运行(7分多钟):

(图8)

还是断了,那就真不知道怎么办才好了。再改变方法,先写到TXT文本文件再导入到xls中,就先不管本文标题了。

运行:

1

2

3

4

5

6

7

8

9

10

11

12

13

2016-03-27 21:47:17.914149

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-27 21:56:16.046792

程序耗时: 0:08:58.132643

在.txt中是正确的:

(图9)

然后在xls文件中选择数据->导入数据即可得到最终结果:

(图10)

封面图片:

(图11)

问题先解决到这,后面的问题有待深入研究。

后期可改进

1.采用多进程/多线程加快爬取速度

2.可考虑采用xlutis模块分多步写入到excel中

3.可考虑改换excel处理模块

3.考虑在Linux环境下进行试验

### Python 爬虫 豆班读书 数据导出 Excel 表格 无数据 的解决方案 在处理 Python 爬虫抓取的数据并将其导出至 Excel 文件的过程中,如果遇到生成的 Excel 表格中无数据的情况,可能涉及以下几个方面的原因分析与解决办法: #### 可能原因一:数据未成功写入 Pandas DataFrame Pandas 是一种强大的数据分析工具,在将爬取的数据存储到列表后再转换成 DataFrame 进行操作时,需确保数据结构的一致性和完整性。如果 `book_names` 或其他变量为空或者长度不一致,则可能导致最终无法正常创建 DataFrame。 - **验证数据有效性** 需要在构建 DataFrame 前打印各列表的内容及其长度来确认是否有缺失项或异常值存在[^1]。 ```python print(len(book_names), book_names[:5]) # 打印前五个书籍名称以及总数量 print(len(book_urls), book_urls[:5]) # 同样检查URLs部分 ``` - **调整DataFrame初始化逻辑** 如果发现某些字段确实存在问题可以考虑填充默认值或将错误记录排除在外再重新组装新的DataFrame对象实化过程如下所示: ```python import pandas as pd data = {&#39;书名&#39;: book_names, &#39;链接&#39;: book_urls} # 创建字典形式的数据集 df = pd.DataFrame(data) # 将其转化为DataFrame格式以便后续操作 ``` --- #### 可能原因二:Excel 导出配置不当 当使用 Pandas 提供的方法尝试把 DataFrame 中的信息保存为 CSV 文件或者是直接转存为 XLSX 类型文件时,可能会因为参数设置失误而导致目标位置上的实际产出物里面没有任何实质性的内容显示出来。 - **指定正确的路径和编码方式** 对于中文环境下的系统来说,默认情况下 UTF-8 编码可能是更好的选择之一;另外也要注意绝对地址书写是否准确无误等问题所在之处[^2]: ```python df.to_excel(&#39;E:/output/douban_books_top250.xlsx&#39;, index=False, encoding=&#39;utf_8_sig&#39;) ``` 上述代码片段中的 `&#39;E:/output/douban_books_top250.xlsx&#39;` 应替换为你希望储存结果的具体目录及文件命名组合而成的目标字符串表达式。同时通过设定 `index=False`, 我们能够避免额外增加不必要的索引列占据空间资源浪费现象发生. --- #### 可能原因三:第三方库版本冲突或其他技术障碍 有时即使按照标准流程执行完毕之后仍然得不到预期效果的话,也许是因为所依赖的一些外部软件包之间存在着兼容性矛盾亦或是内部实现细节有所改变所致的缘故使得原本可行的功能现在变得不可用了起来。 因此建议先升级所有涉及到的相关模块达到最新稳定发行版状态然后再试一次看看情况如何变化再说吧! ```bash pip install --upgrade pandas openpyxl xlwt pywin32 ``` 完成更新动作以后记得重启 IDE 工作区以刷新加载最新的改动成果哦! --- ### 总结 综上所述,针对 Python 爬虫抓取豆瓣读书数据后生成 Excel 表格却出现空白的现象可以从三个方面入手排查解决问题即核查原始采集得到的各项资料清单是否存在遗漏状况、审查导表环节各项指令语句编写规范程度还有就是留意各个辅助插件之间的相互协作关系这三个维度展开深入探讨研究直至找到根本症结所在为止方才能彻底根除此类故障隐患风险点的存在可能性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值