用Requests和正则表达式爬取猫眼电影(TOP100+最受期待榜)

2023-11-18

目标站点分析

目标站点(猫眼榜单TOP100):
在这里插入图片描述
如下图,猫眼电影的翻页offset明显在URL中,所以只要搞定第一页的内容加上一个循环加上offset就可以爬取前100。
第一页
第二页

流程框架

1、抓取单页内容

利用requests请求目标站点,得到单个网页HTML代码,返回结果。

2、正则表达式分析

根据HTML代码分析得到电影的排名、地址、名称、主演、上映时间、评分等信息。

3、保存至文件

通过文件的形式将结果保存,每一部电影一个结果一行Json字符串。

4、开启循环及多线程

对多页内容遍历,开启多线程提高抓取速度。

实战

1、抓取单页内容

兴致勃勃地码了一段代码,用来获得第一页的内容:

import requests
from requests.exceptions import RequestException


#提取单页内容,用try,except方便找bug
def get_one_page(url):
    try:
        response = requests.get(url)      
        if response.status_code == 200:#如果状态码为200,说明请求成功
            return response.text
        return response.status_code#否则请求失败,返回状态码果
    except RequestException:
        return None

def main():
    url= 'http://maoyan.com/board/4'
    html = get_one_page(url)
    print(html)

if __name__ == '__main__':
    main()

结果很尴尬,直接来了个403状态码,说明请求失败了。
在这里插入图片描述

回顾一下之前学的知识:使用Requests库来进行爬虫的详解
headers在爬虫中是非常必要的,很多时候如果请求不加headers,那么你可能会被禁掉或出现服务器错误…
解决办法:加入headers试试看(做一个浏览器的伪装),只需要向get方法传入headers参数就好了,具体的headers内容直接就用文中给出的例子就行。

import requests
from requests.exceptions import RequestException

headers = {'User-Agent':'Mozilla/5.0(Macintosh;Intel Mac OS X 10_11_4)AppleWebKit/537.36(KHTML,like Gecko)Chrome/52.0.2743.116 Safari/537.36'}
#提取单页内容,用try,except方便找bug
def get_one_page(url):
    try:
        
        response = requests.get(url, headers=headers)#传入headers参数
        if response.status_code == 200:
            return response.text
        return response.status_code
    except RequestException:
        return None

def main():
    url= 'http://maoyan.com/board/4'
    html = get_one_page(url)
    print(html)

if __name__ == '__main__':
    main()

在这里插入图片描述
呼呼,打印出了一堆内容,说明这回已经请求成功了。再次说明了请求时加入headers参数的重要性。

2、正则表达式分析

我们想要从爬取到的内容中提取6个信息:排名,封面(超链接),标题,演员,上映时间,评分。
先来看看每一个电影在网页中的结构是怎样的,这样才能知道该怎么写正则表达式:
在这里插入图片描述
仔细研究上图,红框中的正是我们要提取的信息,那么只要将它们置于正则表达式的7个括号中(最后的评分是分开的,所以需要2个括号来选中),并且在括号两旁做出正确的限定,那么这个正则表达式还是很好写的。
代码如下(注意要导入re库):

def parse_one_page(html):#定义一个函数用来解析html代码
	#生成一个正则表达式对象
	pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a' #此处换行
		+'.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
		+'.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',re.S)
	items = re.findall(pattern,html)

对输出的结果再进行格式化处理,使输出更美观:

#items是一个list,其中的每个内容都是一个元组
#将杂乱的信息提取并格式化,变成一个字典形式
	for item in items:
		yield { #构造一个字典
			'index': item[0],
			'image': item[1],
			'title': item[2],
			'actor': item[3].strip()[3:],#做一个切片,去掉“主演:”这3个字符
			'time': item[4].strip()[5:],#做一个切片,去掉“上映时间:”这5个字符
			'score': item[5]+item[6]#将小数点前后的数字拼接起来
		}

再修改一下main函数:

def main():
    url= 'http://maoyan.com/board/4'
    html = get_one_page(url)
    for item in parse_one_page(html):#item是一个生成器
    	print(item)

运行一下看看:
在这里插入图片描述
效果还可以吧~

3、保存至文件

定义一个函数用来将上面提取的信息保存到文件中:

def write_to_file(content):
	with open('result.txt','a',encoding='utf-8') as f:
	#a表示模式是“追加”;采用utf-8编码可以正常写入汉字
		f.write(json.dumps(content, ensure_ascii = False) + '\n')#不允许写入ascii码
		#content是一个字典,我们需要转换成字符串形式,注意导入json库		
		f.close()

再修改一下main函数:


def main():
    url= 'http://maoyan.com/board/4'
    html = get_one_page(url)
    for item in parse_one_page(html):#item是一个生成器
    	print(item)
    	write_to_file(item)

运行一下看看:
在这里插入图片描述
成功保存为文件啦,看看内容,没问题:
在这里插入图片描述

4、开启循环及多线程

循环:

再看看网页的特点,点击下一页时,offset这个参数会增加10:
在这里插入图片描述
在这里插入图片描述
我们只需要修改一下主函数就可以了,给它添加一个offset参数,实现10个页面的抓取:

def main(offset):
    url= 'http://maoyan.com/board/4?offset='+str(offset)#把offset参数以字符串形式添加到url中
    html = get_one_page(url)
    for item in parse_one_page(html):#item是一个生成器
    	print(item)
    	write_to_file(item)

还有起始部分:

if __name__ == '__main__':
    for i in range(10):#构造一个数组实现0,10,20,...,90的循环
    	main(i*10)

运行看看结果(为了展示更美观,在代码中把超链接这个信息去掉了):
在这里插入图片描述
在这里插入图片描述
很棒!

多进程

采用多进程的方法可以提高运行的效率:

from multiprocessing import Pool
if __name__ == '__main__':

    	pool = Pool()#创建一个进程池
    	pool.map(main,[i*10 for i in range(10)])#map方法创建进程(不同参数的main),并放到进程池中

总结

非常顺利的爬取了猫眼电影TOP100,关键在于正则表达式的写法。
全部代码如下:

import requests
from requests.exceptions import RequestException
import re
import json
from multiprocessing import Pool

headers = {'User-Agent':'Mozilla/5.0(Macintosh;Intel Mac OS X 10_11_4)AppleWebKit/537.36(KHTML,like Gecko)Chrome/52.0.2743.116 Safari/537.36'}
#提取单页内容,用try,except方便找bug
def get_one_page(url):
    try:
        
        response = requests.get(url, headers=headers)#传入headers参数
        if response.status_code == 200:
            return response.text
        return response.status_code
    except RequestException:#捕获这个类型的异常
        return None

def parse_one_page(html):#定义一个函数用来解析html代码
	#生成一个正则表达式对象
	pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a' #此处换行
		+'.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
		+'.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',re.S)
	items = re.findall(pattern,html)
	#items是一个list,其中的每个内容都是一个元组
	#将杂乱的信息提取并格式化,变成一个字典形式
	for item in items:
		yield { #构造一个字典
			'index': item[0],
			#'image': item[1],
			'title': item[2],
			'actor': item[3].strip()[3:],#做一个切片,去掉“主演:”这3个字符
			'time': item[4].strip()[5:],#做一个切片,去掉“上映时间:”这5个字符
			'score': item[5]+item[6]#将小数点前后的数字拼接起来
		}

def write_to_file(content):
	with open('result.txt','a',encoding='utf-8') as f:
	#a表示模式是“追加”;采用utf-8编码可以正常写入汉字
		f.write(json.dumps(content, ensure_ascii = False) + '\n')#不允许写入ascii码
		#content是一个字典,我们需要转换成字符串形式,注意导入json库		
		f.close()


def main(offset):
    url= 'http://maoyan.com/board/4?offset='+str(offset)#把offset参数以字符串形式添加到url中
    html = get_one_page(url)
    for item in parse_one_page(html):#item是一个生成器
    	print(item)
    	write_to_file(item)


if __name__ == '__main__':

    	pool = Pool()#创建一个进程池
    	pool.map(main,[i*10 for i in range(10)])#map方法创建进程(不同参数的main),并放到进程池中

爬取最受欢迎榜

原理还是一样的,只需要确定一下要筛选什么信息(因为这和TOP100略有不同),并且修改一下正则表达式和一些小细节即可。

def parse_one_page(html):#定义一个函数用来解析html代码
	
	pattern = re.compile('<dd>.*?"board-index.*?">(\d+)</i>.*?href.*?data-src.*?</a>.*?board-item-main.*?name">.*?title.*?">(.*?)</a>.*?star">(.*?)</p>.*?'
				+'releasetime">(.*?)</p>.*?</dd>', re.S)
	items = re.findall(pattern, html)
	
	
	#items是一个list,其中的每个内容都是一个元组
	#将杂乱的信息提取并格式化,变成一个字典形式
	for item in items:
		yield { #构造一个字典
			'index': item[0],
					#'image': item[1],
			'title': item[1],
			'actor': item[2].strip()[3:],#做一个切片,去掉“主演:”这3个字符
			'time': item[3].strip()[5:],#做一个切片,去掉“上映时间:”这5个字符
			
		}

结果:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用Requests和正则表达式爬取猫眼电影(TOP100+最受期待榜) 的相关文章

随机推荐

  • Java--集合知识再补充(Map集合)

    下面就是我整理的部分学习笔记 学无止境 加油 为方便对多个对象的操作 就对对象进行存储 集合就是存储对对象最常用的一种方式 数组长度是固定的 且可以存储基本数据类型 集合可变 集合只能存储对象 Collection 下有两个子接口 为Lis
  • 权限验证-JWT认证

    JWT 1 什么是JWT JSON Web Token 通过数字签名的方式 以JSON对象为载体 在不同的服务终端之间安全的传输信息 2 JWT有什么用 JWT最常见的场景就是授权认证 一旦用户登录 后续每个请求都将包含JWT 系统在每次处
  • CentOS7 - systemd服务及开启关闭服务命令

    RHEL CentOS 7 0中一个最主要的改变 就是切换到了systemd 它用于替代红帽企业版Linux前任版本中的SysV和Upstart 对系统和服务进行管理 systemd兼容SysV和Linux标准组的启动脚本 Systemd是
  • oracle date 和 timestamp区别

    在今天的工作中 学到了以下几个知识点 一 date和timestamp 的区别 date类型是Oracle常用的日期型变量 他的时间间隔是秒 两个日期型相减得到是两个时间的间隔 注意单位是 天 例如 查看一下当前距离伦敦奥运会开幕还有多长时
  • c++ multiple definition of 问题解决方法

    问题描述 有一个 h头文件 两个 cpp文件都引用了这个 h文件 在 h文件中声明了一些全局变量或函数 编译时报错 multiple definition of 原因 好像是由于多次包含 然后编译 cpp文件是重复 定义了 解决方法 1 使
  • Linux 通过RPM包安装 MySQL 8.0

    Linux平台上推荐使用RPM包来安装Mysql MySQL 提供了以下RPM包的下载地址 MySQL MySQL服务器 你需要该选项 除非你只想连接运行在另一台机器上的MySQL服务器 MySQL client MySQL 客户端程序 用
  • 一、安卓笔记(1)—Android Studio下的的APP目录结构

    一 Android Studio工程目录 1 gradle文件夹包含的是gradle工具的各个版本 不需要手动去填写 自动生成的 Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具 它使用一种基
  • C#开发Windows窗体应用程序的步骤

    使用C 开发应用程序时 一般包括创建项目 界面设计 设置属性 编写程序代码 保存项目 程序运行等6个步骤 1 创建项目 在Visual Studio2017开发环境中选择 文件 新建 项目 菜单 弹出 新建项目 对话框 如图8 1所示 图8
  • Linux环境下Ubuntu系统中下载gvim及相关配置

    分享一下Linux环境下gvim的下载以及自己的相关配置 也方便自己以后重新进行虚拟机的相关配置时进行参考 相关代码带有简略注释 Ubuntu版本18 04 6 首先是下载 命令窗口打开位置无所谓 在命令行中输入以下代码 sudo apt
  • Qt信号槽-原理分析

    转载一篇关于Qt信号槽原理解析的文章 讲解的很详细 有的地方可能有点深度 不过还是能很大程度上的帮助理解信号槽原理 一 问题 moc预编译在干嘛 signals和slots关键字产生的理由 信号槽连接方式有什么区别 信号和槽函数有什么区别
  • 性能优化面试题

    目录 1 当修改一个数据时 不想整个页面都被重新渲染 只想要渲染变更数据的那一部分 怎么做 2 页面是否可以快速加载 3 是否允许用户快速开始与之交互 4 怎么让滚动和动画流畅 5 怎么图片优化 6 骨架屏 合理的loading 7 长列表
  • 30款建模软件

    从入门级3D建模软件到中级再到高级的3D建模软件 从小白到大师相信总有一款适合你 下面是小编为大家列出的30款建模软件以及介绍 供您大开眼界 Google Sketchup 一款极受欢迎并且易于使用的3D设计软件 根据创作过程 开发了一套设
  • 冒泡排序(java)——3种方法

    这里的冒泡是按照从小到大的顺序来的 思想 将相邻的元素两两比较 当一个元素大于右侧相邻的元素时 交换他们的位置 当一个元素小于右侧相邻的元素时 不做任何改变 一 第一种方法 public static void main String ar
  • Python字典出现重复的键,以最后出现的值为准

    Python3 6及之后 字典是有序的了 出现重复的键 以最后出现的值为准 test dict a 1 a 2 a 3 print test dict 输出 a 3
  • 使用easyExcel导出excel文件

    1 导入jar包
  • Android Studio下载、安装和配置+SDK+tools下载(无敌超级详细版本)

    下载 Anderson Studio是Google为Android提供的官方IDE工具 下载地址 http www android studio org 此处下载3 4 1版本 安装环境要求 其中JDK的最低版本是1 7 所以系统空闲内存至
  • 一个普通聊友质问腾讯客服的录音 过瘾哈

    http yumengluentan uueasy com read htm tid 146 html
  • 关于区块链几个证书的理解

    关于区块链几个证书的理解 FISCO BCOS 1 说明 在FISCO BCOS中 证书这个概念有许多的概念 会在环境与节点配置 部署 构链等步骤中反复出现 例如链证书 机构证书 节点证书和客户端证书等 如下对这些概念和关系进行一个适当的理
  • 使用 source insight 代码跳转时出现 symbol not found 问题

    P S 本篇博客是根据自己的经验来写的 如果大家有不同意见随时交流 1 使用 source insight 代码跳转功能时出现 symbol not found 问题一般是有三种可能 在你添加代码时没有选择 Add tree 选项 创建 p
  • 用Requests和正则表达式爬取猫眼电影(TOP100+最受期待榜)

    目标站点分析 目标站点 猫眼榜单TOP100 如下图 猫眼电影的翻页offset明显在URL中 所以只要搞定第一页的内容加上一个循环加上offset就可以爬取前100 流程框架 1 抓取单页内容 利用requests请求目标站点 得到单个网