用户
搜索
  • TA的每日心情
    慵懒
    2020-8-22 10:09
  • 签到天数: 76 天

    连续签到: 1 天

    [LV.6]常住居民II

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    31

    主题

    197

    帖子

    1137

    魔法币
    收听
    0
    粉丝
    11
    注册时间
    2015-12-29

    幽默灌水王春秋游侠积极活跃奖限定版春秋段子手i春秋签约作者春秋文阁

    发表于 2020-9-25 16:27:38 13341
    上次我们通过glidedsky的第一关实现了获取到单页的数据,但是可能有些小伙伴会觉得只是获取到一些数字并不能直观的体现出Python爬虫的方便之处。
    所以今天我跟大家分享一个小小的案例,这不是在家空闲时间比较多,又不想太过于颓废,于是我打算在豆瓣挑选一些评分比较高的书分享给大家。
    当然手动筛选工作量太大了,所以我决定用python写一个爬虫,爬取豆瓣图书TOP250的简单数据,并整理成表格保存在本地。
    网页元素分析
    因为上篇文章只讲了获取单页数据,所以这次我们的目标也是先获取一页数据。
    这个页面本身比较干净,数据也很清晰,获取会比较方便一些。
    还是先f12查看页面元素,确定所要获取的数据。

    通过审查元素可以看出所有数据特点:
    书名包含在a标签中,作者及出版社等信息保存在命名为pl的p标签中,并通过斜杠分割不同数据,评分保存在class=allster_rums的span标签中,评价人数在class='pl'的span标签中,
    发现了吗?这些数据没有做任何加密,同时每一个数据标识各不相同,非常容易分辨。
    这也是为什么很多人在初学爬虫时都会接触到爬取豆瓣top250例子的原因,因为数据内容有用,爬取难度相对较小。
    这里还需要注意一个问题,就是这部分图书并不全是中文书籍,还有一部分是外文书,这就导致了他们之间有一个地方数据有差别:

    外文书会多出一个译者名字,所以之后在保存数据到表格文件中时,需要特别注意。
    代码实现
    在开始之前还是先明确一下程序执行流程:
    • 访问网页
    • 获取源代码
    • 提取数据
    • 分别保存到excel文件中
      首先解决访问网页和获取源代码的问题:
    import requestsfrom bs4 import BeautifulSoupurl = 'http://book.douban.com/top250?start='headers = {        'cookie':'你自己的cookie',        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}response = requests.get(url,headers=headers).textbs4 = BeautifulSoup(response,'html.parser')print(bs4)
    获取到之后当然就是对数据进行提取
    bookName = bs4.find_all('div',class_='pl2')for book in bookName:        name = book.find('a')        name = name.text.strip()        name = name.replace(' ','')        print(name)
    这段代码首先在获取到的html文本中寻找Class=pl2的div元素

    这是没有提取a标签中书名时的原始数据
    find_all()是BeautifulSoup模块提供的一个用来快速查询数据的方法,返回一个列表。
    所以我们下面使用for循环遍历出所有找到的数据。
    从上面的图片中可以看到,只匹配div元素的话会有很多干扰数据,我们此时只想要一个书名,也就是a标签的文本信息。
    所以我们还需要在列表中使用find()方法匹配到a标签的内容,然后使用strip方法去除两边空格,使用replace方法将文本中多余的空格替换为空,最终可以得到:
    获取到数据之后,我们希望能够把它存放到excel文件中的话需要用到一个外部库xlwt

    使用pip命令安装xlwt(因为我的电脑中同时安装了py2和py3,所以将pip的版本进行了区分,只有一个python的话直接用pip即可)
    然后使用 import xlwt在程序中引入该模块。
    wb = xlwt.Workbook()ws = wb.add_sheet('test_sheet')ws.write(0,0,'书名')ws.write(0,1,'出版信息')ws.write(0,2,'评价人数')ws.write(0,3,'评级')wb.save('doubanTest.xls')
    首先实例化workbook()对象,然后调用了add_sheet()方法为这个excel文件新建一个表

    关于这个add_sheet()方法,前面说过python调用的外部模块保存在**Python安装目录\Lib\site-packages**下,所以我们可以在这个目录下找到Workbook类文件,从这里面查看add_sheet()的具体实现方法以及主要参数。

    注意这段代码中引入Worksheet这个文件,本文中主要用到的是Worksheet中的write()方法,即将数据保存到表格文件中。

    在Worksheet.py中找到write函数,注释给的非常详细,r和c分别是row和column的缩写,表示从0开始的行和列。
    label参数默认为空,表示数据。
    这样一来上述代码就通了,表示在第一行从第一列开始分别添加标题。

    所有东西都设置好了之后就是保存这个文件,使用Workbook中的save()方法

    传入一个文件名即可。
    这块啰嗦了一点,主要还是希望大家能够养成多看引入模块源文件的习惯。
    其他数据的获取其实和获取书名类似
    获取作者及出版信息
    i = 1j = 1k = 1l = 1authors = bs4.find_all('p',class_='pl')for author in authors:        anthor = author.text        ws.write(j,1,author)        j+=1        print(author)
    获取评分及评价人数
    rating_nums = bs4.find_all('div',class_='star clearfix')for rating in rating_nums:        star = rating.find_all('span')        reg = '\d+'        vote = re.findall(reg,star[2].text)        ws.write(k,2,vote)        ws.write(l,3,star[1].text)        k+=1        l+=1wb.save('doubanTest.xls')
    ijkl分别代表的是不同的行数,作用在于换行时使用。
    这里还有一点需要注意的地方,在获取评分及评价人数时,因为两个数据在同一个div下保存,而且是同级别的span标签并列表示的。
    所以使用find_all()方法获取到全部span标签内容后可以使用下标的方式查询到不同的数据。

    至此,我们的程序就大功告成了,运行后会在该目录下生成一个douban.xls文件

    如果出现这种错误

    说明你之前已经生成了一个doubanTest.xls文件而且没有关闭它。
    解决办法是更改生成的文件名或者将原文件关闭。

    感谢分享
    剑未佩妥出门已是江湖
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册