检查网页源代码

首先让我们来检查豆瓣top250的源代码,一切网页爬虫都需要从这里开始。F12打开开发者模式,在元素(element)页面通过Ctrl+F直接搜索你想要爬取的内容,然后就可以开始编写正则表达式了。

如下是我们将要爬取内容的html局部区域:

  1. <div class="item">
  2. <div class="pic">
  3. <em class="">1</em>
  4. <a href="https://movie.douban.com/subject/1292052/">
  5. <img width="100" alt="肖申克的救赎" src="https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp" class="">
  6. </a>
  7. </div>
  8. <div class="info">
  9. <div class="hd">
  10. <a href="https://movie.douban.com/subject/1292052/" class="">
  11. <span class="title">肖申克的救赎</span>
  12. <span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>
  13. <span class="other">&nbsp;/&nbsp;月黑高飞(港) / 刺激1995(台)</span>
  14. </a>
  15. <span class="playable">[可播放]</span>
  16. </div>
  17. <div class="bd">
  18. <p class="">
  19. 导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>
  20. 1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
  21. </p>
  22. <div class="star">
  23. <span class="rating5-t"></span>
  24. <span class="rating_num" property="v:average">9.7</span>
  25. <span property="v:best" content="10.0"></span>
  26. <span>2668670人评价</span>
  27. </div>
  28. <p class="quote">
  29. <span class="inq">希望让人自由。</span>
  30. </p>
  31. </div>
  32. </div>
  33. </div>

当然,在Chrome中页面是这样的:

匹配正则表达式

<em class="">1</em>这显然是‘’索引‘’可以用于匹配序号

相应正则表达式为:

  1. <em class="">(\d+)</em>

其中\d+的含义是匹配1个及以上的数字

正则表达式详解请看:正则表达式完整入门教程,含在线练习

正则表达式速查表请看:正则表达式速查表

<a href="https://movie.douban.com/subject/1292052/">这个表示的是标题对应的超链接,也就是对应电影的详情页,如果我们要做进一步的内容爬取,这个链接也是值得保存的。

这里介绍一下re.S参数,它可以让我们跨行匹配正则表达式。而且我们知道,正则表达式越详细,匹配的精确度就越高,于是我们可以将上下两行一起匹配。

  1. <em class="">1</em>
  2. <a href="https://movie.douban.com/subject/1292052/">

相应的正则表达式为:

  1. '<em class="">(\d+)</em>.*?<a href="(.*?)">.*?'

然后我来解释下为什么我们要加括号(),这是因为,有的时候我们想要的不是每一个存在变化的变量,它们仅仅需要作为通配符来使用,于是我们将需要返回的匹配值加上括号作为返回值,未加括号的正则表达式匹配的值不会被返回。上面的.*?就是不会被返回的正则表达式。

接下来看看我们的完整正则表达式吧:

  1. pattern = re.compile(
  2. '<em class="">(\d+)</em>.*?<a href="(.*?)">.*?' +
  3. '<img width="100" alt=".*?" src="(.*?)" class=""' +
  4. '>.*?<span class="title">(.*?)</span>.*?<span ' +
  5. 'class="other">&nbsp;/&nbsp;(.*?)</span>.*?<div ' +
  6. 'class="bd">.*?<p class="">.*?导演: (.*?)&nbsp.*?<br>' +
  7. '.*?(\d{4})&nbsp;/&nbsp;(.*?)&nbsp;/&nbsp;(.*?)\n' +
  8. '.*?</p>.*?<span class="rating_num" property="v:' +
  9. 'average">(.*?)</span>',
  10. re.S)

正则表达式中.表示任意字符;*表示前置字符任意次数;?表示前置字符可有可无。

这个号,即是常用的连接字符串的用法。我们可以发现,上述表达式一共有10个括号(),也就是说最终会在一个item中返回10个值,以列表(数组)形式。

  • 正则中没有括号时,返回的是 list,list的元素是 str ;
  • 正则中有括号时,返回的是 list,list的元素是 tuple ,tuple 中的各项对应的是括号中的匹配结果

下面我们来认识一下re的几个库函数:

  • re.compile 是预编译正则表达式函数,是用来优化正则的,它将正则表达式转化为对象

  • re.compile 函数用于编译正则表达式,生成一个 Pattern 对象,pattern 是一个字符串形式的正则表达式

  • pattern 是一个匹配对象( Regular Expression),它单独使用就没有任何意义,需要和findall(), search(), match()搭配使用。

  • 使用re.S参数以后,正则表达式会将这个字符串作为一个整体,将“\n”当做一个普通的字符加入到这个字符串中,在整体中进行匹配,而不是在一行内进行匹配。

  • re.findall返回string中所有与pattern相匹配的全部字串,返回形式为数组

完整代码

导入包

  1. # json包
  2. import json
  3. #正则表达式包
  4. import re
  5. import requests
  6. from requests import RequestException

定义获取html函数

  1. #函数:获取一页html
  2. def get_one_page(url):
  3. try:
  4. headers = {
  5. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
  6. }
  7. # Response对象返回包含了整个服务器的资源
  8. # Response对象的属性,有以下几种
  9. # r.status_code: HTTP请求的返回状态,200表示连接成功,404表示失败
  10. # 2.r.text: HTTP响应内容的字符串形式,即,url对应的页面内容
  11. # 3.r.encoding:从HTTP header中猜测的响应内容编码方式
  12. # 4.r.apparent_encoding:从内容中分析出的响应内容编码方式(备选编码方式)
  13. # 5.r.content: HTTP响应内容的二进制形式
  14. response = requests.get(url, headers=headers, timeout=1000)
  15. if response.status_code == 200:
  16. return response.text
  17. except requests.exceptions.RequestException as e:
  18. print(e)

定义解析html函数【正则】

  1. #函数:解析一页html
  2. def parse_one_page(html):
  3. pattern = re.compile(
  4. '<em class="">(\d+)</em>.*?<a href="(.*?)">.*?' +
  5. '<img width="100" alt=".*?" src="(.*?)" class=""' +
  6. '>.*?<span class="title">(.*?)</span>.*?<span ' +
  7. 'class="other">&nbsp;/&nbsp;(.*?)</span>.*?<div ' +
  8. 'class="bd">.*?<p class="">.*?导演: (.*?)&nbsp.*?<br>' +
  9. '.*?(\d{4})&nbsp;/&nbsp;(.*?)&nbsp;/&nbsp;(.*?)\n' +
  10. '.*?</p>.*?<span class="rating_num" property="v:' +
  11. 'average">(.*?)</span>',
  12. re.S)
  13. #使用re.S参数以后,正则表达式会将这个字符串作为一个整体,将“\n”当做一个普通的字符加入到这个字符串中,在整体中进行匹配,而不是在一行内进行匹配。
  14. #re.findall返回string中所有与pattern相匹配的全部字串,返回形式为数组
  15. #上述pattern正好有10个括号
  16. items = re.findall(pattern, html)
  17. for item in items:
  18. yield {
  19. 'index': item[0],
  20. 'page_src': item[1],
  21. 'img_src': item[2],
  22. 'title': item[3],
  23. 'other_title': item[4],
  24. 'director': item[5],
  25. 'release_date': item[6],
  26. 'country': item[7],
  27. 'type': item[8],
  28. 'rate': item[9],
  29. }

定义保存内容函数

  1. #函数:将内容写入文件
  2. def write_to_file(content):
  3. with open('douban_movie_rankings.txt', 'a', encoding='utf-8') as f:
  4. f.write(json.dumps(content, ensure_ascii=False) + '\n')

定义主函数

  1. #主控函数
  2. def main():
  3. #用于翻页
  4. for offset in range(10):
  5. #获取网址
  6. url = f'https://movie.douban.com/top250?start={offset * 25}&filter='
  7. #获取html文件
  8. html = get_one_page(url)
  9. for item in parse_one_page(html):
  10. print(item)
  11. write_to_file(item)

定义魔法函数

  1. if __name__ == '__main__':
  2. main()

原创作者:孤飞-博客园

原文链接:https://www.cnblogs.com/ranxi169/p/16565717.html

正则表达式实战:最新豆瓣top250爬虫超详细教程的更多相关文章

  1. 最新豆瓣top250爬虫案例代码分析[注释齐全]

    导入包 # json包 import json #正则表达式包 import re import requests from requests import RequestException 定义爬取 ...

  2. 数学规划求解器lp_solve超详细教程

    前言 最近小编学了运筹学中的单纯形法.于是,很快便按奈不住跳动的心.这不得不让我拿起纸和笔思考着,一个至关重要的问题:如何用单纯形法装一个完备的13? 恰巧,在我坐在图书馆陷入沉思的时候,一位漂亮的小 ...

  3. Struts2+Spring4+Hibernate4整合超详细教程

    Struts2.Spring4.Hibernate4整合 超详细教程 Struts2.Spring4.Hibernate4整合实例-下载 项目目的: 整合使用最新版本的三大框架(即Struts2.Sp ...

  4. Github上传代码菜鸟超详细教程【转】

    最近需要将课设代码上传到Github上,之前只是用来fork别人的代码. 这篇文章写得是windows下的使用方法. 第一步:创建Github新账户 第二步:新建仓库 第三部:填写名称,简介(可选), ...

  5. WebRTC VideoEngine超详细教程(三)——集成X264编码和ffmpeg解码

    转自:http://blog.csdn.net/nonmarking/article/details/47958395 本系列目前共三篇文章,后续还会更新 WebRTC VideoEngine超详细教 ...

  6. 安装64位Oracle 10g超详细教程

    安装64位Oracle 10g超详细教程 1. 安装准备阶段 1.1 安装Oracle环境 经过上一篇博文的过程,已经完成了对Linux系统的安装,本例使用X-Manager来实现与Linux系统的连 ...

  7. NumPy 超详细教程(3):ndarray 的内部机理及高级迭代

    系列文章地址 NumPy 最详细教程(1):NumPy 数组 NumPy 超详细教程(2):数据类型 NumPy 超详细教程(3):ndarray 的内部机理及高级迭代 ndarray 对象的内部机理 ...

  8. NumPy 超详细教程(2):数据类型

    系列文章地址 NumPy 最详细教程(1):NumPy 数组 NumPy 超详细教程(2):数据类型 NumPy 超详细教程(3):ndarray 的内部机理及高级迭代 文章目录 NumPy 数据类型 ...

  9. NumPy 超详细教程(1):NumPy 数组

    系列文章地址 NumPy 最详细教程(1):NumPy 数组 NumPy 超详细教程(2):数据类型 NumPy 超详细教程(3):ndarray 的内部机理及高级迭代 文章目录 Numpy 数组:n ...

随机推荐

  1. linux篇-linux下ffmpeg安装

    1最近自己搭建的公司服务端转化视频不可以,我想应该是ffmpeg的问题,头痛 准备这两个源码包 2安装,先解压 ffmpeg-4.1.4.tar.bz2 yasm-1.3.0.tar.gz 3先安装y ...

  2. Spring Ioc源码分析系列--Bean实例化过程(一)

    Spring Ioc源码分析系列--Bean实例化过程(一) 前言 上一篇文章Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理已经完成了对 ...

  3. conda install和pip install区别

    conda ≈ pip(python包管理) + virtualenv(虚拟环境) + 非python依赖包管理 级别不一样conda和yum比较类似,可以安装很多库,不限于Python.conda是 ...

  4. 【Java面试】TCP协议为什么要设计三次握手?

    一个工作5年的粉丝,最近去面试了很多公司,每次都被各种技术原理题问得语无伦次. 由于找了快1个月时间的工作,有点焦虑,来向我求助. 我能做的只是保证每天更新一个面试题,然后问他印象最深刻的一个面试题是 ...

  5. C++ 之多态总结

    前言 最近为了完成数据库系统的实验,又复习起了<C++ Primer>,上一次看这本巨著也是大二下的六月份,那时看面向对象程序编程这一章还云里雾里的,没有领会多态的奥妙,学完 Java 之 ...

  6. vue 使用npm install安装依赖失败 【问题分析与解决】

    1 进入项目根目录,先通过 npm install 命令安装项目所需依赖,再通过 vue ui 命令打开 Vue Cli 提供的图形化界面,选择项目所在文件夹将项目导入. 出现问题 npm insta ...

  7. WAVE音频格式及及转换代码

    音频信号的读写.播放及录音 python已经支持WAV格式的书写,而实时的声音输入输出需要安装pyAudio(http://people.csail.mit.edu/hubert/pyaudio).最 ...

  8. Linux安装Anaconda3完整教程

    Linux安装Anaconda3完整教程 欢迎关注H寻梦人公众号 相关链接 官方安装Anaconda3教程 [手把手教你]如何在Linux系统搭建jupyter notebook CentOS8.2安 ...

  9. 【python量化】将Transformer模型用于股票价格预测

    本篇文章主要教大家如何搭建一个基于Transformer的简单预测模型,并将其用于股票价格预测当中.原代码在文末进行获取.小熊猫的python第二世界 1.Transformer模型 Transfor ...

  10. PostgreSQL 9.1 飞升之路

    PostgreSQL upgrade 以升级 PostgreSQL 9.1 至 PostgreSQL 11 (跨越 9.2.9.3.9.4.9.5.9.6.10 六个大版本) 为例,本文将分享一下过去 ...