文档章节

爬虫入门(二)——静态页面爬取:豆瓣爬取近六年出版评分在7分以上的漫画

o
 osc_w9s1w4o0
发布于 2019/04/13 17:29
字数 1254
阅读 9
收藏 0

精选30+云产品,助力企业轻松上云!>>>

Before

在实现一个例子之前,首先要明确自己想要获得怎样的结果:爬取近六年出版评分在7分以上的漫画

最后我想要得到的信息是所有满足要求的书名

要求有二:1、近六年出版,即出版时间 >= 2013年 2、评分在7分以上

接下来针对我们的要求,去观察页面元素

我们观察一下页面(https://book.douban.com/tag/%E6%BC%AB%E7%94%BB?start=0&type=T),找到这两点信息的位置(图中黄色底部分信息)

在检查元素里找到这两点信息的位置:年份信息包含在一个class为"pub"的标签中

评分信息包含在class为star clearfix的div标签的子标签span:class为rating_nums的信息中

注意:因为在后面爬虫的时候发现中间有些页面因为没有评分而没有class为rating_nums的标签,因此在爬取评分信息的时候

我们要先找到star clearfix 的这个div标签,再对具体情况进行处理

书名:在包含title元素的a标签中

 

结束上述准备以后,明确我们要提取的信息

1、书名:在包含title元素的a标签中

2、出版年份:在class为'pub'的div信息中

3、评分:在class为star clearfix的div标签的子标签span:class为rating_nums的信息中

 

 

本例中使用的网页解析工具是BeautifulSoup,比较好上手,合适网路爬虫初学者的一个可以代替正则表达式的网页解析工具

首先要安装,可以直接使用pip进行安装

安装代码:pip install bs4

安装成功后就可以直接在python环境下使用这个包里的内容了

 

接下来就可以开始去构造爬虫


 

 

import内容如下

1 import urllib.request
2 from bs4 import BeautifulSoup
3 import re
4 import time #豆瓣robots.txt文件限制了爬取的时间速度间隔最低为5s,因此需要自行限速,避免被禁

 

初始化访问urllist列表

 1 '''
 2 构建访问url列表
 3 '''
 4 urllist=[]
 5 for i in range(1, 51): #初始化urllist,注意到地址的不同要分开对待
 6     if i > 1:
 7          urllist.append('https://book.douban.com/tag/%%E6%%BC%%AB%%E7%%94%%BB?start=%s0&type=T' % i)  # 遍历2到50页的数据
 8     else :
 9         urllist.append('https://book.douban.com/tag/%E6%BC%AB%E7%94%BB?start=0&type=T')
10 # for i in urllist:
11 #     print(i)

构造爬虫信息筛选函数,返回每一页符合条件的书名列表(详细解释见备注)

 1 def choose_comics(url):
 2     page = urllib.request.urlopen(url) # BeautifulSoup本身并不能访问网页,所以需要使用urllib库或者requests库去获取网页源代码,再交给BeautifulSoup进行处理
 3     bsoup = BeautifulSoup(page,'lxml') # 此处后面要标明'lxml',不然会产生未写明解析器警告
 4 
 5     # print(bsoup.text)
 6     '''
 7     根据before中梳理的筛选信息的思路写出从源代码筛选目的数据的语句
 8     '''
 9     title = [t['title'] for t in bsoup.find_all('a',title=True)] # title获取所有a标签中title内的元素
10     grade = [t.text for t in bsoup.find_all('div',class_ ='star clearfix')] #首先获取star clearfix模块内的内容
11     publication_date = [t.text for t in bsoup.find_all('div', class_='pub')]
12     # print(grade)
13 
14     for i in range(len(grade)):
15         if (re.search(r'.*?([0-9]+\.[0-9]).*?',grade[i])) :# 寻找star clearfix模块中是否存在浮点数,即有评分,否则用0分代替
16             grade[i]=re.search(r'.*?([0-9]+\.[0-9]).*?',grade[i]).group()
17             # print(grade[i])
18         else :
19             grade[i]='0.0'
20     '''
21     上面这个二次筛选信息循环读取评分的处理是为了保证每一个书名对应序号在grade列表中都有对应的评分
22     不至于因为出现没有评分而出现匹配异常的情况
23     '''
24 
25 
26     # print(title)
27 
28     # print(publication_date)
29     # for i in range(len(grade)):
30     #     if grade[i] == '' :
31     #         grade[i] = "0.0"
32 
33     print(grade) # 为了调试用的输出语句,可删去
34 
35     book_list=[]
36      # if len(grade) == len(publication_date):
37     '''
38     对已经获得的list信息进行筛选,把符合出版年份在2013年以后以及评分在7分以上的书本添加到book_list中
39     函数最后返回符合条件的一个书名列表
40     '''
41     for i in range(len(title)):
42         if grade[i] :
43             grade_book = float(grade[i])
44             pattern = re.compile(r'.*?20(\d+).*?')
45             if re.findall(pattern,publication_date[i]) :
46                 date_book = re.findall(pattern,publication_date[i])[0]
47                 date_book = int('20' + date_book)
48                 if (date_book >= 2013 and grade_book >= 7.0) :
49                     book_list.append(title[i])
50 
51     return book_list

 

函数的调用与结果输出:

 1 '''
 2 调用part
 3 '''
 4 all_books=[]
 5 for url in urllist:
 6     time.sleep(5)
 7     all_books.extend(choose_comics(url))
 8 all_books = list(set(all_books))
 9 '''
10 结果展示
11 '''
12 for item in all_books:
13     print(item)

 

实际在用的时候可以把结果列表转为csv存到数据中,不过目前我还不会这个……以后看看能不能导出来


 

最后贴一个爬下来的数据截图!

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

如何将div放置在其容器的底部? - How can I position my div at the bottom of its container?

问题: Given the following HTML: 鉴于以下HTML: <div id="container"> <!-- Other elements here --> <div id="copyright"> Copyright Foo web designs </div> </div> I would like #cop......

富含淀粉
58分钟前
10
0
unity列表控件Horizontal/Vertical/Grid Layout Group用法介绍

1. Grid Layout Group 为Panel控件添加Grid Layout Group,子控件为四个按钮,分别为Grid,Calendar,Gear,User: 默认属性为 为方便演示,按钮的底色为控件自带image,按钮上面的图标为其子...

路过暴风
今天
19
0
Distinct()与lambda? - Distinct() with lambda?

问题: Right, so I have an enumerable and wish to get distinct values from it. 是的,所以我有一个可枚举的,并希望从中获得不同的值。 Using System.Linq , there's of course an ext......

法国红酒甜
今天
16
0
学习编写编译器[关闭] - Learning to write a compiler [closed]

问题: Preferred languages : C/C++, Java, and Ruby. 首选语言 :C / C ++,Java和Ruby。 I am looking for some helpful books/tutorials on how to write your own compiler simply for......

技术盛宴
今天
17
0
OSChina 周一乱弹 —— 毛巾又怎么样?!我在乎的是大姐姐温柔的怀抱!

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @薛定谔的兄弟 :分享洛神有语创建的歌单「我喜欢的音乐」: 《雨 因你而下,于你而止》- Seto 手机党少年们想听歌,请使劲儿戳(这里) @Dan...

小小编辑
今天
48
2

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部