爬虫入门教程

article/2025/9/10 21:18:40

文章目录

  • 前言
  • 一、学习爬虫前所需掌握的内容
  • 二、爬取数据
    • 2.1 如何存储数据
    • 2.2 获取html网络数据
    • 2.3 获取json网络数据
    • 2.4 获取图片数据
  • 三、提取数据
    • 3.1 提取百度热搜信息
    • 3.2 提取豆瓣同城近期活动信息


前言

第一次接触爬虫,这篇博客用于记录学习的过程,将持续进行更新与修正,希望大家指正错误。本文所学习的案例为:爬取豆瓣电影的评分、评价等信息,进行数据分析。

一、学习爬虫前所需掌握的内容

我们进入豆瓣官网,我现在们想要爬取电影的评分、评价等信息。
在这里插入图片描述
提取这些信息用处很大,例如对于评价信息,可以提取里面的关键词等信息,并进行分析做一个词云图。
在这里插入图片描述


如果我们需要爬取这些信息,则需要以下基础:
①会使用Python完成相关代码
②会分析html
③会使用csv文件、sql存储数据

二、爬取数据

2.1 如何存储数据

由于是入门,我们使用csv文件存储数据,csv又叫逗号分隔符。使用csv文件存储文件的相关代码如下所示:

import csv  # 利用csv模块完成数据读取与存储的相关操作# 新建一个list,存储一些信息
goods = [[1, 'jack', 18],[2, 'Lucy', 19],[3, 'Lily', 18],[4, 'Tom', 20]]# 正常使用open步骤如下:即首先创建文件流,然后进行操作,最后关闭文件流。
# f = open('persons.csv')
# ......
# f.close()
# 但是有时候会忘记关闭文件流,导致资源浪费,所以可以使用with。
# 在with的缩进里面执行文件相关操作,当超出with的缩进时,资源自动释放。# 默认的文件读写模式为 文本模式 t
# 写入所有图片、音乐、视频       mode='wb'
# 写入普通文本                 mode='wt'# Windows系统写入内容时,具有内容的各行之间会出现空白行,所以需要加上newline=''。具体原因参见博客中的链接# 写内容到文件中
with open('persons.csv', mode='wt', newline='') as f:w_file = csv.writer(f)    # 将f管道升级为csv管道w_file.writerows(goods)   # 写入内容print('写入完毕')# 读取文件中的内容
with open('persons.csv', mode='r') as f:r_file = csv.reader(f)for row in r_file:print(row)

Windows系统的用户有一些需要注意的地方,即写入数据到csv文件里时会出现空行,具体原因参见:关于python中csv模块writerows()功能写入二维列表数据时会出现空行的一点思考

2.2 获取html网络数据

获取网络数据需要使用request模块,官方文档链接:request官方文档
在这里插入图片描述


现在我们需要了解浏览器的开发者工具,因为通过开发者工具可以查看请求和响应的详细信息。我们在浏览器页面右键点击,选择检查元素
在这里插入图片描述


接着便会弹出以下界面,其中Element便是html代码。
在这里插入图片描述


我们选择Network,查看响应的相关信息。
在这里插入图片描述


其中Doc文件里面信息重要,界面如下。在General一栏中,Request URL代表我们要访问的地址。Request Method代表请求的方法,有GET和POST两种。
在这里插入图片描述


我们可以分析里面Request Headers的内容,看看我们是发送了一个什么东西让服务器给了我们response并允许我们访问。Request Headers中User Agent最为重要,它表示了当前是谁在访问。服务器通过User Agent认为是浏览器在进行访问。
在这里插入图片描述


我们开始进行访问,需要保存的是响应的返回内容。
在这里插入图片描述


代码如下:

import locale    # 查看系统的编码方式
import requests# 一个字典,保存User-Agent信息
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 OPR/78.0.4093.231"
}# 使用requests发送get类型的请求,同时将requests伪装成由浏览器发起
url = 'https://movie.douban.com/explore#!type=movie&tag=热门&sort=recommend&page_limit=20&page_start=0'
response = requests.get(url, headers=headers)      # headers参数需要输入一个子字典类型的参数
code = response.status_code                        # 返回码,正确时为200# 看一下系统的编码方式,Windows默认是GBK。
# print(locale.getpreferredencoding(False))if code == 200:# 获取的响应数据data = response.text# 将相应数据保存到douban.html文件中# open函数采用的编码方式依赖于系统,而我们在pycharm中打开html文件是使用UTF-8。因此,使用open函数时将编码方式更改为UTF-8with open('douban.html', mode='w', encoding="utf-8") as f:f.write(data)
else:print('请求有误!')

得到返回的html原始数据后,我们看一看,并在浏览器中打开。
在这里插入图片描述
我们发现效果如下,电影的信息都不显示,说明我们想要的信息不在这个链接。
在这里插入图片描述

2.3 获取json网络数据

因此,我们得继续回去分析。只要我们的数据没在Doc里面,那么加载方式可能是异步加载。如何验证是否是异步加载的呢?操作步骤如下:
在这里插入图片描述
我们对比几次的URL如下:
Request URL: https://movie.douban.com/j/search_subjects?type=movie&tag=%E8%B1%86%E7%93%A3%E9%AB%98%E5%88%86&sort=time&page_limit=20&page_start=0

Request URL: https://movie.douban.com/j/search_subjects?type=movie&tag=%E8%B1%86%E7%93%A3%E9%AB%98%E5%88%86&sort=time&page_limit=20&page_start=20

Request URL: https://movie.douban.com/j/search_subjects?type=movie&tag=%E8%B1%86%E7%93%A3%E9%AB%98%E5%88%86&sort=time&page_limit=20&page_start=40


我们可以发现只是最后的page_start不一样。我使用浏览器打开page_start=20对应的URL,界面如下,返回了json信息。
在这里插入图片描述


我们可以得到:
Document返回html格式数据,格式如下:

<html>
......
<html>

XHR(ajax)返回json格式数据,格式如下:

{
data:["",""]
}

如果觉得json格式较乱,可以使用bejson进行格式化校验,让格式更清晰。
在这里插入图片描述
获取json数据代码如下:

import requestsheaders = {"User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 OPR/78.0.4093.231"
}url = 'https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0'
response = requests.get(url, headers=headers)
code = response.status_codeif code == 200:data = response.json()    # 获取的响应数据是json类型print(type(data))         # data的类型是stringdata = str(data)          # 将字典类型转成str类型with open('movies.txt', mode='w', encoding="utf-8") as f:f.write(data)
else:print('请求有误!')

2.4 获取图片数据

如果我们想提取电影的海报图片,首先查看bejson格式化后的json信息。
在这里插入图片描述
可以看出cover项对应的应该就是电影海报所在位置,我们复制网址并检查,发现正是存储电影海报的位置。
在这里插入图片描述


我们将该网址设置为需要爬取的URL,代码如下:

import requestsheaders = {"User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 OPR/78.0.4093.231"
}url = "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2615830700.webp"
response = requests.get(url, headers=headers)
code = response.status_codeif code == 200:# 获取的响应数据是二进制data = response.contentwith open('picture.jpg', mode='wb') as f:f.write(data)
else:print('请求有误!')

爬取图片如下:
在这里插入图片描述

三、提取数据

将各类数据爬取后,我们开始从中提取出数据。我们可以使用XPATH,它能够解析html,也能解析xml。XPATH的详细语法可参照:XPATH语法

3.1 提取百度热搜信息

我们从最开始爬取的百度html文件如下:
在这里插入图片描述
浏览器中打开后界面如下,我们如何从中提取出热搜信息呢?
在这里插入图片描述


我们可以看出,热搜信息位置如下:
在这里插入图片描述
剩余的热搜信息(点击换一批可以看到)则在这里:
在这里插入图片描述


提取热搜信息代码如下:

import requests
from lxml import etreeheaders = {"User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 OPR/78.0.4093.231"
}
url = 'https://www.baidu.com'response = requests.get(url, headers=headers)
code = response.status_codeif code == 200:data = response.text# 将获取的网络数据交给etree进行解析html = etree.HTML(data)hotsearchs = html.xpath('//ul[@class="s-hotsearch-content"]/li/a/span[2]/text()')print(hotsearchs)
else:print('请求有误!')

效果如下:
在这里插入图片描述

3.2 提取豆瓣同城近期活动信息

希望提取的豆瓣同城近期活动信息如下图所示:
在这里插入图片描述


我们希望提取活动标题和时间信息。其中,活动标题所处位置如下:
在这里插入图片描述


活动时间所处位置如下:
在这里插入图片描述


提取标题和时间信息代码如下:

import requests
from lxml import etree
import re
import csv# 1. 发出请求,获取响应数据
headers = {"User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 OPR/78.0.4093.231"
}
url = 'https://beijing.douban.com/events/week-all'
response = requests.get(url, headers=headers)if response.status_code == 200:data = response.text# 2. 解析数据html = etree.HTML(data)titles = html.xpath('//ul[@class="events-list events-list-pic100 events-list-psmall"]/li/div[2]/div/a/span/text()')print(titles)times = html.xpath('//ul[@class="events-list events-list-pic100 events-list-psmall"]/li/div[2]/ul/li[1]/text()')print(times)# 处理times中的\n和空格# 准备一个列表times1存放处理好的数据times1 = []for t in range(1,len(times),4):ti = re.sub(r'\s+','',times[t])times1.append(ti)print(ti)# 3. 存储数据titles = zip(titles, times1)with open('tongcheng.csv', mode='w', newline='', encoding='utf-8') as f:w_file = csv.writer(f)w_file.writerows(titles)
else:print('error')

http://chatgpt.dhexx.cn/article/ryq1knrH.shtml

相关文章

「爬虫教程」吐血整理,最详细的爬虫入门教程

初识爬虫 学习爬虫之前&#xff0c;我们首先得了解什么是爬虫。来自于百度百科的解释&#xff1a; 网络爬虫&#xff08;又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在FOAF社区中间&#xff0c;更经常的称为网页追逐者&#xff09;&#xff0c;是一种按照一定的规则&…

Python爬虫之入门保姆级教程,学不会我去你家刷厕所

注重版权&#xff0c;转载请注明原作者和原文链接作者&#xff1a;Bald programmer 今天这个教程采用最简单的爬虫方法&#xff0c;适合小白新手入门&#xff0c;代码不复杂 文章目录 今天这个教程采用最简单的爬虫方法&#xff0c;适合小白新手入门&#xff0c;代码不复杂首先…

Java单元测试使用mock【转载】

1、什么是Mock? mock是在测试过程中&#xff0c;对于一些不容易构造/获取的对象&#xff0c;创建一个mock对象来模拟对象的行为。比如说你需要调用B服务&#xff0c;可是B服务还没有开发完成&#xff0c;那么你就可以将调用B服务的那部分给Mock掉&#xff0c;并编写你想要的返…

Java代码实现单元测试

单元测试&#xff1a;在编写java代码的时候&#xff0c;如果我们想去运行一个Java程序&#xff0c;那么必须创建一个main方法&#xff0c;但这样比较麻烦 比如现在我们想去测试HDFS的JavaAPI的文件上传和文件下载功能 如果使用main方法的话&#xff0c;那么我们需要创建两个J…

java单元测试(@Test)

初学者在写java代码的时候&#xff0c;可能会因为写一个小功能就要写一个类&#xff0c;写一个main方法而苦恼。其实java的工程师在很早的时候就提供了解决的方案。就是我们今天要讲 的Junit测试。 在使用的时候首先需要配置环境&#xff1a; 一、英文&#xff1a; 选中一个…

java单元测试方法的使用

单元测试方法的使用 java单元测试是最小的功能单位测试代码&#xff0c;我们在编写大型程序的时候&#xff0c;需要写成千上万个方法或函数&#xff0c;这些函数的功能可能很强大&#xff0c;但我们在程序中只用到该函数的一小部分功能&#xff0c;如果想要测试这些方法函数的…

java单元测试的编写及运行方法

java单元测试的方法 1、为什么要进行单元测试 因为单元测试相当于测试的某个功能点&#xff0c;不是针对整个业务进行的测试&#xff0c;例如如果只想调试某个类下的功能&#xff0c;但又想把多个类写在一个java文件里&#xff0c;就可以采用单元测试的方法 2、怎么创建及运…

Java单元测试框架 - JUnit

导航 我们为什么需要单元测试框架&#xff1f;为工程添加JUnit支持编写JUnit单元测试案例JUnit常用注解JUnit常用断言JUnit案例Spring整合 我们为什么需要单元测试框架&#xff1f; 当我们需要对一段代码进行测试时&#xff0c;怎么样让他快速跑起来呢&#xff1f;一个很自然的…

java单元测试之mock篇

java单元测试之mock篇 一、什么是mock&#xff1f;二、为什么要进行mock&#xff1f;三、IDEA中使用Mock3.1、引入mock所需依赖3.1、IDEA单元测试必备快捷键3.2、Mock测试相关注解Mock注解InjectMocks注解调用PowerMockito.spy()方法Mock使用方式或者技巧静态方法mockStaticPre…

Java单元测试之Mock框架

一、引言二、为什么要用Mock三、Mock使用场景四、Mock定义五、Mock框架五、Mockito5.1 Mockito基本使用5.2 MockMVC测试5.2.1 初始化MockMvc对象5.2.2 接口测试5.2.3 常用API 一、引言 实际工作中&#xff0c;可能会遇到如下情况&#xff1a; 场景一&#xff1a;依赖接口不通…

Java单元测试实践-01.单元测试概述与示例

Java单元测试实践-00.目录&#xff08;9万多字文档700多测试示例&#xff09; https://blog.csdn.net/a82514921/article/details/107969340 1. 前言 以下内容为本人以开发人员的视角&#xff0c;在平时进行单元测试过程中的总结。主要内容为通用的&#xff0c;不限制具体业务…

如何写Java单元测试

本文引自https://www.cnblogs.com/ysw-go/p/5447056.html 什么是单元测试   我们在编写大型程序的时候&#xff0c;需要写成千上万个方法或函数&#xff0c;这些函数的功能可能很强大&#xff0c;但我们在程序中只用到该函数的一小部分功能&#xff0c;并且经过调试可以确定…

Java单元测试总结

[版权申明] 非商业目的注明出处可自由转载 博文地址&#xff1a; 出自&#xff1a;shusheng007 文章目录 概述单元测试概念测试项目单元测试工具JUnitMockito SpringBoot测试总结 概述 关于为什么要做单元测试是老生常谈了&#xff0c;越是小公司越不重视单元测试&#xff0c;…

java单元测试junit

进行单元测试则需要添加junit的依赖&#xff1a; ##JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck. ##对于java来说JUnit是一个单元测试的框架<dependency><groupId>junit</groupId><artifactId>junit</arti…

Java 单元测试

什么是单元测试 单元测试&#xff08;unit testing&#xff09;&#xff0c;是指对软件中的最小可测试单元进行检查和验证&#xff0c;简单来说就是测试部分代码&#xff0c;对代码中的问题快速定位&#xff0c;及时修复。 什么是JUnit JUnit就是一个Java语言的单元测试框架…

JAVA基础之单元测试

目录 1、单元测试介绍 2、环境搭建 2.1 JUnit 4 2.2 JUnit 5 3、快速上手 3.1 JUnit 4 3.2 JUnit 5 1、单元测试介绍 单元测试就是针对最小的功能单元编写测试代码&#xff0c;Java程序最小的功能单元是方法&#xff0c;因此&#xff0c;单元测试就是针对Java方法的测试…

Java基础单元测试

本篇博文目录: 1.单元测试(1) 测试Java方法(原生) 2. JUnit 5(1) JUnit 5简单使用的例子(2) JUnit5常用注解(3) JUnit5常用注解的使用(4).JUnit5内置断言 1.单元测试 单元测试就是针对最小的功能单元编写测试代码。Java程序最小的功能单元是方法&#xff0c;因此&#xff0c;对…

如何进行Java 单元测试

一、概述 Java 单元测试是指对软件中的最小可测试单元进行测试&#xff0c;以保证代码的质量和正确性&#xff0c;并且可以加速开发过程。本文将全面详细地介绍 Java 单元测试相关知识点&#xff0c;包括单元测试的定义、优点和流程、JUnit 测试框架、Mockito 框架、持续集成、…

Java之单元测试(JUnit单元测试框架)

一、概述 单元测试就是针对最小的功能单元编写测试代码&#xff0c;Java程序最小的功能单元是方法&#xff0c;所以单元测试就是针对Java方法的测试&#xff0c;进而检查方法的正确性。常规测试有什么问题&#xff1f; 只有一个main方法&#xff0c;如果一个方法的测试失败了…

(60)Java基础 --单元测试

目录 一、测试的概念 二、使用Junit4.x进行单元环境 1、环境搭建 2、使用步骤 3、常见注解 三、规范的Junit测试方式 四、断言 1、为什么要使用断言 2、什么是断言(猜测) 3、常用API 一、测试的概念 先认识到测试的重要性&#xff1a;优秀的软件不是开发出来的,而是…