python爬取豆瓣首页热门栏目详细流程

记录一下爬取豆瓣热门专栏的经过,通过这篇文章,你能学会requests,HTMLParser,json的基本使用,以及爬取网页内容的基本思路。

使用模块

  1,获取豆瓣首页代码:首先我们需要访问豆瓣页面,获取首页的源码。这里推荐使用第三方库:requests,相比python内置的 urllib 模块,requests使用起来更简单,功能更全面

  2,对获取的代码进行解析:对于解析html代码,已经有很多功能强大的框架能使用,如Scrapy,PySpider,Beautiful Soup等,这里我们只是学习下爬虫的基本使用,所以内建的 HTMLParser 足够使用了

  3,对获取的数据进行处理: json

思路分析

既然我们需要的只是热门专栏模块的数据,那么我们需要一个标志来告诉我们:下面的代码就是专栏模块了,准备获取数据。同样我们需要知道当前

读取的是图片、标题还是栏目类别,以此将数据储存到相应的字段中。总的来说,我们最起码应该通过代码来实现以下几点:

  1,获取网页源码

  2,通过自定义方法解析html

  3,通过标志位判断当前数据是否是我们需要的数据

  4,通过分析代码结构决定将要储存的数据结构

  5,将数据按照特定格式进行本地储存

豆瓣官网:https://www.douban.com/,分析一下我们需要爬取模块的代码:

可以看到,我们需要爬取的数据都在 ul.time-list 这个代码块里,那么我们的标志位就是:当开始标签为 ul并且具有类名 time-list时,我们就要获取数据了,当结束标签为 ul 时,停止解析,继续分析代码结构,每个 li 里面包含了对应数据里面的 详情页跳转链接,图片地址,标题以及专栏类别,那么我们的数据结构到这里也就很清楚了:一个 li 块对应一条数据,每条数据由四个字段组成:

  详情页跳转链接 href --> 这里我们考虑了一下, 还是通过第二个a标签来获取,它具有统一的类名title,同时我们还能获取 标题title,

  图片地址 imgUrl --> 通过每个li代码块里面唯一img标签的src属性可以轻松获取,

  标题 title --> 通过 a.title获取,

  专栏类别 type --> 唯一的 span 标签获取

tip:像上面我们选取数据的标志位一样,img的alt可以获取标题,a标签的文本也可以获取标题,两个a标签都能获取跳转链接不管是爬虫还是平时其他的开发,我们经常会遇到,同一个需求有多种方法实现,这时候我们就需要思考一下哪一种方法更简洁,冷静分析后的编码不一定最优秀,但自己肯定印象深刻(说远了,回归正题)。

编码实现

通过上面的准备工作,我们已经确定了需要引入的模块,解析事件触发标志位,需要获取的数据,储存的数据结构,可以正式开始编码了:

requests是第三方库,需要另外安装,其他的是内置模块,直接引入即可:

1 import requests
2 from html.parser import HTMLParser
3 from html.entities import name2codepoint
4 import json

获取豆瓣首页源码:

1 r = requests.get(‘https://www.douban.com/‘, timeout = 3)

是的,通过 requests获取网页只需要一行代码,timeout为获取页面超时时间,通过 r.text 就是我们需要的html源码,r.encoding可以获取网页编码格式,当然requests还有其他的方法供我们使用,

如 带参数的url: r = requests.get(url, params={.....}),获取数据等

解析豆瓣首页源码:

HTMLParser 里已经封装好了针对html的各种事件处理,如 开始标签,结束标签,标签属性,标签文本,注释,特殊字符,不了解的可以看下这个:

https://www.liaoxuefeng.com/wiki/1016959663602400/1017784593019776,很简单很清晰

 1 class MyHTMLParser(HTMLParser):
 2     def __init__(self):
 3         super().__init__()
 4         # 是否开始解析
 5         self._allowRun = False
 6
 7         # 创建dist备用:储存数据
 8         self.hotList = {‘data‘: []}
 9
10         # 每一个 li 块数据储存
11         self.listItem = {}
12
13         # 当前解析标签类型的标志位
14         self.tagType = ‘‘
15
16     # 开始标签及 标签属性
17     def handle_starttag(self, tag, attrs):
18         if tag == ‘ul‘ and (‘class‘, ‘time-list‘) in attrs:
19             self._allowRun = True
20
21         # 若当前是开启解析状态
22         if self._allowRun:
23             if tag == ‘a‘ and (‘class‘, ‘title‘) in attrs:
24                 self.tagType = ‘a‘
25                 for (key, value) in attrs:
26                     if key == ‘href‘:
27                         self.listItem[key] = value
28             if tag == ‘img‘:
29                 for (key, value) in attrs:
30                     if key == ‘src‘:
31                         self.listItem[‘imgUrl‘] = value
32
33             if tag == ‘span‘:
34                 self.tagType = ‘span‘
35
36     # 结束标签
37     def handle_endtag(self, tag):
38         self.tagType = ‘‘
39         if tag == ‘ul‘:
40             self._allowRun = False
41
42         if tag == ‘li‘:
43             if len(self.listItem) != 0:
44                 self.hotList[‘data‘].append(self.listItem)
45                 self.listItem = {}
46
47     # 空标签及 标签属性
48     def handle_startendtag(self, tag, attrs):
49         if self._allowRun:
50             if tag == ‘img‘:
51                 for (key, value) in attrs:
52                     if key == ‘src‘:
53                         self.listItem[‘imgUrl‘] = value
54
55     # 标签文本
56     def handle_data(self, data):
57         if self._allowRun:
58             if self.tagType == ‘a‘:
59                 self.listItem[‘title‘] = data
60                 self.taga = False
61             elif self.tagType == ‘span‘:
62                 self.listItem[‘type‘] = data
63
64     # 注释
65     def handle_comment(self, data):
66         pass
67
68     # HTML entity 字符
69     def handle_entityref(self, name):
70         pass
71
72     # Numeric 字符
73     def handle_charref(self, name):
74         pass
75
76 parser = MyHTMLParser()77 parser.feed(r.text)

代码说明:我们必须知道在解析过程中,实例方法是按照源码顺序循环执行的,也就是说在同一个实例方法里,我们可以针对不同的标签或其他条件来进行不同的操作。我们所有的解析操作都是针对 ul.time-list 代码块的,所以我们需要一个开关,当前代码是 ul.time-list时才执行我们自定义的解析操作,这个开关就是上面代码里的 _allowRun,当开始标签是 ul.time-list的是否为 True,当结束标签是 ul 的是否为False,而只有当 _allowRun 为 True的时候,我们才继续解析当前的标签是 a 还是 img 或者 span。由于我们要在 文本解析事件 handle_data 中获取 a 标签的文本作为字段 title 的值,span标签的文本作为字段 type 的值,所以我们需要一个标志位变量来供我们在执行 handle_data 的时候判断当前解析的文本是属于 a 还是 span,这个标志位变量就是上面代码中 tagType,在 handle_starttag 中赋值,在 handle_endtag 中清空。我们将每一条数据储存在 listItem 中,当结束标签为 li 时,说明我们的对一个 li 代码块解析完毕,listItem 储存了我们需要的单挑数据,将 listItem 添加到 hotList中并清空  listItem 。执行上面代码,我们已经将数据储存在实例属性 hotList里面,我们可以在终端输出 parser.hotList:

储存数据

接下来就是将数据储存到本地文件中,而写入数据也是非常简单:

1 with open(‘hotList.json‘, ‘w‘) as f:
2     json.dump(parser.hotList, f)

在当前目录里打开 hotList.json 文件,可以看到如下数据:

数据倒是写入了,但是中文却没有如愿显示,而且对于追求美观的我们来说也无法接受,所以我们需要指定写入编码格式,以及格式化:

1 with open(‘hotList.json‘, ‘w‘, encoding="utf-8") as f:
2     json.dump(parser.hotList, f, ensure_ascii = False, indent = 4)

我们在写入的时候指定编码格式为 utf-8: encoding="utf-8",在 json.dump写入数据时增加了两个参数:ensure_ascii = False 禁止进行 ascii转码,indent = 4:按缩进为 4个单位格式化数据,当然我们还可以将字段进行排序,只需要加上字段:sort_keys = True,按需选择即可,再打开 hotList.json 文件查看:

 1 {
 2     "data": [
 3         {
 4             "imgUrl": "https://img1.doubanio.com/dae/niffler/niffler/images/1c6e77ec-c493-11e9-84c0-0242ac110008.jpg",
 5             "href": "https://m.douban.com/time/column/164?dt_time_source=douban-web_anonymous",
 6             "title": "伤别离与共春风——唐宋词的情感世界",
 7             "type": "音频专栏"
 8         },
 9         {
10             "imgUrl": "https://img1.doubanio.com/dae/niffler/niffler/images/511ccf86-b8fc-11e9-b188-0242ac110008.jpg",
11             "href": "https://m.douban.com/time/column/163?dt_time_source=douban-web_anonymous",
12             "title": "世界记忆大师教你快速提升记忆力",
13             "type": "视频专栏"
14         },
15         {
16             "imgUrl": "https://img1.doubanio.com/dae/niffler/niffler/images/74897a9e-880c-11e9-bd82-0242ac11001b.jpg",
17             "href": "https://m.douban.com/time/column/159?dt_time_source=douban-web_anonymous",
18             "title": "黑白之间:二十八堂书法练习课",
19             "type": "视频专栏"
20         },
21         {
22             "imgUrl": "https://img3.doubanio.com/dae/niffler/niffler/images/6f488990-a773-11e9-b587-0242ac110011.jpg",
23             "href": "https://m.douban.com/time/column/161?dt_time_source=douban-web_anonymous",
24             "title": "马伯庸的冷门书单",
25             "type": "音频专栏"
26         },
27         {
28             "imgUrl": "https://img1.doubanio.com/dae/niffler/niffler/images/6c46cb9c-ac61-11e9-97e2-0242ac11000c.jpg",
29             "href": "https://m.douban.com/time/column/162?dt_time_source=douban-web_anonymous",
30             "title": "听!解说式音乐会——古典音乐聆听指南",
31             "type": "视频专栏"
32         },
33         {
34             "imgUrl": "https://img3.doubanio.com/dae/niffler/niffler/images/ebd421cc-9968-11e9-ad2c-0242ac110006.jpg",
35             "href": "https://m.douban.com/time/column/158?dt_time_source=douban-web_anonymous",
36             "title": "从格里菲斯到诺兰——影迷都在看的电影结构大师课",
37             "type": "视频专栏"
38         },
39         {
40             "imgUrl": "https://img3.doubanio.com/dae/niffler/niffler/images/fa83f054-9633-11e9-a82e-0242ac110006.jpg",
41             "href": "https://m.douban.com/time/column/157?dt_time_source=douban-web_anonymous",
42             "title": "打开电影声音的魔盒——好莱坞声音设计大师课",
43             "type": "视频专栏"
44         },
45         {
46             "imgUrl": "https://img3.doubanio.com/dae/niffler/niffler/images/81788c8e-8e53-11e9-b51e-0242ac110010.jpg",
47             "href": "https://m.douban.com/time/column/156?dt_time_source=douban-web_anonymous",
48             "title": "一剧之本——好莱坞编剧教父大师课",
49             "type": "视频专栏"
50         },
51         {
52             "imgUrl": "https://img3.doubanio.com/dae/niffler/niffler/images/5d7d70aa-8b25-11e9-a08f-0242ac110012.jpg",
53             "href": "https://m.douban.com/time/column/155?dt_time_source=douban-web_anonymous",
54             "title": "老叶说电影——90分钟看懂中国电影产业",
55             "type": "视频专栏"
56         },
57         {
58             "imgUrl": "https://img3.doubanio.com/dae/niffler/niffler/images/e2e59078-828e-11e9-a465-0242ac110012.jpg",
59             "href": "https://m.douban.com/time/column/154?dt_time_source=douban-web_anonymous",
60             "title": "好莱坞特效大师课——从概念艺术到3D建模",
61             "type": "视频专栏"
62         }
63     ]
64 }

这样就只有两个字:嘘服。

总结

这个例子只是用来熟悉爬虫基本操作和思维逻辑,真正用到项目中还是得结合其他框架,如 Beautiful Soup,就可以获取指定代码片段进行解析而不需要像我们上面那样设置开关或标志位。有兴趣的朋友可以自己动手试试。

与诸君共勉。

原文地址:https://www.cnblogs.com/wbsndbf/p/11439415.html

时间: 2024-10-12 23:56:50

python爬取豆瓣首页热门栏目详细流程的相关文章

利用Python爬取豆瓣电影

目标:使用Python爬取豆瓣电影并保存MongoDB数据库中 我们先来看一下通过浏览器的方式来筛选某些特定的电影: 我们把URL来复制出来分析分析: https://movie.douban.com/tag/#/?sort=T&range=0,10&tags=%E7%94%B5%E5%BD%B1,%E7%88%B1%E6%83%85,%E7%BE%8E%E5%9B%BD,%E9%BB%91%E5%B8%AE 有3个字段是非常重要的: 1.sort=T 2.range=0,10 3.tag

Python3 爬虫实例(三) -- 爬取豆瓣首页图片

序 前面已经完成了简单网页以及伪装浏览器的学习.下面,实现对豆瓣首页所有图片爬取程序,把图片保存到本地一个路径下. 首先,豆瓣首页部分图片展示 这只是截取的一部分.下面给出,整个爬虫程序. 爬虫程序 这个爬取图片的程序采用伪装浏览器的方式,只不过是加了处理图片的模块. ''' 批量下载豆瓣首页的图片 采用伪装浏览器的方式爬取豆瓣网站首页的图片,保存到指定路径文件夹下 ''' #导入所需的库 import urllib.request,socket,re,sys,os #定义文件保存路径 targ

python爬取豆瓣小组700+话题加回复啦啦啦python open file with a variable name

需求:爬取豆瓣小组所有话题(话题title,内容,作者,发布时间),及回复(最佳回复,普通回复,回复_回复,翻页回复,0回复) 解决:1. 先爬取小组下,所有的主题链接,通过定位nextpage翻页获取总过700+条话题: 2. 访问700+ 链接,在内页+start=0中,获取话题相关的四部分(话题title,内容,作者,发布时间),及最佳回复.回复: 3. 在2的基础上,判断是否有回复,如果有回复才进一步判断是否有回复翻页,回复翻页通过nextpage 获取start=100.start=2

团队-Python 爬取豆瓣电影top250-需求分析

需求:爬取豆瓣电影TOP250 *向用户展示电影的排名,分数,名字,简介,导演,演员,前10条影评信息,链接信息 实现思路: 分析豆瓣电影TOP250的url规则, 编写模块获取相关url 获取全部相关页面的html代码 分析html中有关"排名,分数,名字,简介,导演,演员,前10条影评信息,链接信息"的标签 结合第三方工具包实现信息的提取 编写将"搜集信息"展示出来的模块

python 爬取豆瓣电影评论,并进行词云展示及出现的问题解决办法

本文旨在提供爬取豆瓣电影<我不是药神>评论和词云展示的代码样例 1.分析URL 2.爬取前10页评论 3.进行词云展示 1.分析URL 我不是药神 短评 第一页url https://movie.douban.com/subject/26752088/comments?start=0&limit=20&sort=new_score&status=P 第二页url https://movie.douban.com/subject/26752088/comments?sta

Python 爬取豆瓣TOP250实战

学习爬虫之路,必经的一个小项目就是爬取豆瓣的TOP250了,首先我们进入TOP250的界面看看. 可以看到每部电影都有比较全面的简介.其中包括电影名.导演.评分等. 接下来,我们就爬取这些数据,并将这些数据制成EXCEL表格方便查看. 首先,我们用requests库请求一下该网页,并返回他的text格式. 请求并返回成功! 接下来,我们提取我们所需要的网页元素. 点击“肖申克救赎”的检查元素. 发现它在div class = "hd" -> span class = "

python爬取豆瓣电影首页超链接

什么是爬虫?  我们可以把互联网比作一张大网,而爬虫(即网络爬虫)便是在网上爬行的蜘蛛.把网的节点比作一个个网页,爬虫爬到这就相当于访问了该页面,获取了其信息.可以把节点间的连线比作网页与网页之间的链接关系,这样蜘蛛通过一个节点后,可以顺着节点连线继续爬行到达下一个节点,即通过一个网页继续获取后续的网页,这样整个网的节点便可以被蜘蛛全部爬行到,网站的数据就可以被抓取下来了. 代码: 1 from urllib import request 2 from collections import de

用Python爬取豆瓣Top250的电影标题

所以我们可以这么写去得到所有页面的链接我们知道标题是在 target="_blank"> 标题的位置</a> 之中 所以可以通过正则表达式找到所有符合条件的标题 将内容写入到表格保存起来 下面贴入完整代码 import requests, bs4, re, openpyxl url = 'https://www.douban.com/doulist/3936288/?start=%s' urls = [] 多少页 pages = 10 for i in range(p

python 爬取网页简单数据---以及详细解释用法

一.准备工作(找到所需网站,获取请求头,并用到请求头) 找到所需爬取的网站(这里举拉勾网的一些静态数据的获取)----------- https://www.lagou.com/zhaopin/Python/ 请求头的作用:模拟真实用户进入网站浏览数据-----------headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75