python爬虫教程——科研向

2023-05-16

引言

在科研中,有时需要爬取网站上的文本数据,用于统计分析,或是制作机器学习所用的数据集。

举个例子,假如我们需要在世界野生鸟类声音网XenoCanto中,爬取网站上的鸟类声音标签信息,如下图所示:

世界野生鸟类声音网数据

该网站上的数据量非常大,有67万条数据,手动复制这么大的数据是不现实的。此时,可利用爬虫程序自动获取网页上的数据,保存为表格,便于科研分析。

本博客将以该网站为例,介绍如何利用爬虫代码搜集我们需要的信息。

1. 对网页的理解

网页是由HTML语言(Hyper Text Markup Language,超文本标记语言)进行描述的。

HTML由成对的开始标签和结束标签组成,其中符号<  >表示开始标签,</  >表示结束标签。

标签之间可以嵌套,组成不同层级的标签内容。标签开头的空格数越多,代表其嵌套层数越多。

以下代码是一个简单的HTML内容,其中<html>和</html>是文件开头和结尾的格式,<p>和</p>表示一个段落,中间文本就是该段落的内容。

<html>
    <p> 一个简单的HTML </p>
</html>

可以新建一个test.html文件,用记事本打开,输入该代码,保存后用浏览器打开,就可看到网页结果:

接下来稍微复杂一点,我们在网页中添加一个表格,用<table>和</table>表示。

表格中的每行用<tr>和</tr>表示,tr的含义为table row。

每行中的每列数据用<td>和</td>表示,td的含义为table data。

一个包含表格的网页代码如下:

<html>
    <table> 
        <tr>
            <td> 第一列 </td>
            <td> 第二列 </td>
            <td> 第三列 </td>
        </tr>
        <tr>
            <td> 1 </td>
            <td> 2 </td>
            <td> 3 </td>
        </tr>
    </table>    
</html>

其网页结果:

不同于以上两个简单的示例,实际网页中的标签种类更多,更复杂。

接下来,让我们看看目标网站的HTML代码。

在浏览器页面中,同时按下Ctrl+Shift+C键,进入开发者模式,其中以<!DOCTYPE html>开头的窗口,就是HTML代码窗口啦。将鼠标放置在HTML标签上,网页上对应的内容就会出现蓝色遮罩。点击三角箭头,可以展开或者隐藏某一级标签。

通过人工观察,确定目标数据在<table class="results">标签中,一行数据在一个<tr>标签中,一列数据在一个<td>标签中。其中,class="results"是<table>标签的属性,当网页中存在多个<table>时,可利用属性来定位目标表格。

忽略掉网页内其他数据,该网页HTML进行简化为:

<!DOCTYPE html>
<html>
    ...
    <table class="results">
        ...
        <tr> <!-- 第一行数据 -->
            <td> </td>
            <td> </td>
            ...
        </tr>
        <tr> <!-- 第二行数据 -->
            <td> </td>
            <td> </td>
            ...
        </tr>
        ...
    </table>
    ...
</html>

到此,对目标网页结构的理解已经足够,接下来就是编写爬虫代码,获取目标数据啦。

2. 爬取单个网页

编程语言使用python3,需要三个软件包:requests、BeautifulSoup、csv

安装命令:

pip3 install requests
pip3 install bs4 
# bs4的意思是BeautifulSoup-version4
# csv是python3默认安装,无需额外安装

requests包模拟客户端发送网络请求,接受响应,并获取网页内容。

BeautifulSoup包可作为HTML解析库,从网页内容中提取数据。

csv包用于保存表格数据。

接下来编写爬虫代码,仅需要简单的三步:

(1)请求网页内容

# 从给定链接中,获取网页内容
html = requests.get("https://xeno-canto.org/explore")

(2)提取网页内容

# 按协议解析网页
soup = BeautifulSoup(html.text, 'lxml') 
# 从网页内容中,定位目标表格
table = soup.find('table', attrs={'class': 'results'})
# print(table.text) # 表格文本内容
# 获取网格中所有行  
trs = table.find_all('tr')
data = []
# 遍历每一行
for tr in trs:
    # 获取一行中的所有列
    tds = tr.find_all('td')
    row = []
    # 遍历每一列
    for td in tds:
        row.append(td.text)
    data.append(row)

这里爬虫的核心是两个函数:find()和find_all()

其相同点:

1. 主参数为标签名,也可输入参数attrs={'属性名', '属性值'},返回满足条件的对象。

2. 返回对象可继续提取子对象。

3. 可通过.text成员变量,获取对象的文本内容。

不同点:

1. find()返回满足条件的第一个对象。

2. find_all()返回满足条件的所有对象,可理解返回一个对象列表。

由此可以抽象出三种代码组织方式,如以下代码所示。使用哪种方式,看具体需求而定。

soup = BeautifulSoup(html.text, 'lxml')

# 第一种方式:嵌套find()
a = find('标签名1')
b = a.find('标签名2')
print(b.text)

# 第二种方式:嵌套find_all()
aa = find_all('标签名1')
for a in aa:
    bb = a.find_all('标签名2')
    for b in bb:
        print(b.text)

# 第三种方式:嵌套find()和find_all()
a = find('标签名1')
bb = a.find_all('标签名2')
for b in bb:
    print(b.text)

(3)保存爬取数据

with open('data.csv', 'w') as f:
    # 用逗号分割表格
    csv_writer = csv.writer(f, delimiter=',') 
    for row in data:
        # 向csv文件中写入一行
        csv_writer.writerow(row) 

爬取单个网页内容的完整代码如下:

import requests
from bs4 import BeautifulSoup
import csv

# Step1: 请求网页内容
html = requests.get("https://xeno-canto.org/explore?query=since%3A31&dir=0&order=xc")

# Step2: 提取网页内容
soup = BeautifulSoup(html.text, 'lxml')
table = soup.find('table', attrs={'class': 'results'})
trs = table.find_all('tr')
data = []
for tr in trs:
    tds = tr.find_all('td')
    row = []
    for td in tds:
        row.append(td.text)
    data.append(row)
    
# Step3: 保存爬取数据
with open('data.csv', 'w') as f:
    csv_writer = csv.writer(f, delimiter=',')
    for row in data:
        csv_writer.writerow(row)

可以直接复制粘贴代码,运行一下,看看保存的表格内容。

到这里,恭喜你,你已经会简单的爬虫了!

3. 爬取多个有序网页

接下来,让我们把需求稍微变得复杂一点。

在目标网站中,数据是分页的,有226页!

 

如果爬取一页,就手动更换requests.get()中的网址,显然是不现实的。

幸运的是,这种分页的网址是有序的。

# 第一页网址:
https://xeno-canto.org/explore?query=since%3A31&dir=0&order=xc&pg=1
# 第二页网址:
https://xeno-canto.org/explore?query=since%3A31&dir=0&order=xc&pg=2
...
# 最后一页网址:
https://xeno-canto.org/explore?query=since%3A31&dir=0&order=xc&pg=25583

观察不同页码的网址,可以看出规律:网址末尾的最后一个数字为页数。

按照找到的规律,在代码上加一点逻辑,就可以爬取多个网页啦:

import requests
from bs4 import BeautifulSoup
import csv

page_num = 226
url_prefix = 'https://xeno-canto.org/explore?query=since%3A31&dir=0&order=xc&pg='
file_name = 'data.csv'

f = open(file_name, 'w')
csv_writer = csv.writer(f, delimiter=',')
count = 0
for idx in range(1, page_num+1):
    url = url_prefix + str(idx)
    html = requests.get(url)
    soup = BeautifulSoup(html.text, 'lxml')
    table = soup.find('table', attrs={'class': 'results'})
    trs = table.find_all('tr')
    # 跳过第一行表头
    for tr in trs[1:]: 
        tds = tr.find_all('td')
        row = []
        for td in tds:
            row.append(td.text)
        csv_writer.writerow(row)
        count += 1
    print('爬取页数:', idx, '数据个数:', count, '当前网址:', url)
            
print('所有网页爬取完成!')            

总结

本博客介绍了基于requests、BeautifulSoup、csv三个库实现的爬虫代码。

对目标网页结构有了基本认识后,编写爬虫代码并不复杂。

但在实际项目中,目标网站可能有反爬机制,或者验证码机制,本文方法将无法工作。对于这种情况,可利用Selenium包编写爬虫。

希望本博客能帮助广大科研党入门爬虫。

参考文献

HTML 简介 | 菜鸟教程

通用爬虫模块+requests包的5种作用_request包的作用_-随_风-的博客-CSDN博客

python中beautifulsoup的作用_Python3中BeautifulSoup的使用方法_Screwberry的博客-CSDN博客

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

python爬虫教程——科研向 的相关文章

  • 【STM32】几款常用产品(F1、F4、F7)的区别

    STM32系列单片机 xff0c 是目前极为常用的单片机 xff0c 它以ARM Cortex M为内核 xff0c 具有高性能 低成本 低功耗 可裁剪等特点 其中使用最广泛的是STM32F1 STM32F4 STM32F7系列 xff0c
  • VMware虚拟机看不到共享目录

    VMware虚拟机看不到共享目录 确认VMtools已经装好 xff0c 开启共享文件夹 xff0c 设置好共享目录执行命令 sudo mount t vmhgfs host mnt hgfs 如果出现错误 xff1a Error cann
  • 【Linux基础】Makefile基础入门

    基础Makefile规则和样例展示 基础的makefile样例 目标 xff1a 依赖 命令 单文件编译 mian o main c gcc c mian c o mian 多文件编译 mian o main c mian h includ
  • Json基础

    Json是什么 JSON 或者 JavaScript 对象表示法是一种轻量级的基于文本的开放标准 xff0c 被设计用于可读的数据交换 约定使用 JSON 的程序包括 C xff0c C 43 43 xff0c Java xff0c Pyt
  • STM32 BOOT引起硬件死机

    STM32的三种启动方式依靠BOOT0和BOOT1两个引脚的电平来决定 xff0c ST官方推荐的是串联10k电阻然后在接高电平或接地 我用0R直接接地的 xff0c 没有串联10k电阻 xff0c 造成STM32的硬件死机 在实际的应用中
  • 远程 sshd提示:Server unexpectedly closed network connection

    root 64 xx vim etc ssh sshd config 修改端口为3330 root 64 xx iptables I INPUT p tcp dport 3330 j ACCEPT 添加防火墙3330端口 允许 root 6
  • linux驱动开发流程和方法

    方法一 xff1a 将驱动编入内核的方法 手把手教你写第一个Linux驱动程序 https blog csdn net morixinguan article details 54620088 方法二 xff1a 简单实例讲解linux的m
  • Ubuntu 出现apt-get: Package has no installation candidate问题解决办法

    apt get install tftpd tftp openbsd inetd 提示apt get Package has no installation candidate 解决方法如下 xff1a 先检查虚拟机网络是否NAT模式 xf
  • Vim/gVim 中文显示为乱码的解决办法

    打开vimrc文件 xff0c 在vim的安装目录下可以找到该文件 xff0c 或在windows下是在vim gvim下输入 edit vim vimrc 在文件的末尾添加一句 set fileencodings 61 utf 8 gbk
  • 关于字,半字,字节之间的关系

    一直搞不清楚字 xff0c 半字 xff0c 字节之间的关系 xff0c 查了一下资料 xff0c 明白了 字 xff0c 半字 xff0c 字节 大小是根据不同的操作系统来说的 xff0c 32位系统 字 gt 32bit 半字 gt 1
  • android json解析及简单例子

    JSON的定义 xff1a 一种轻量级的数据交换格式 xff0c 具有良好的可读和便于快速编写的特性 业内主流技术为其提供了完整的解决方案 xff08 有点类似于正则表达式 xff0c 获得了当今大部分语言的支持 xff09 xff0c 从
  • vim-plug的使用方法

    vim plug介绍 Vim plug 是一个自由 开源 速度非常快的 并行地安装或更新插件 xff0c 极简的 vim 插件管理器 GIT获取和安装 https git scm com 插件获取 https github com june
  • .NetCore swagger发布到iis时访问api出现404的解决方案

    介绍 使用netcore作为纯后端提供api已经变得越来越频繁 xff0c swagger也成为很多人的选择 通常会在代码中限制ASPNETCORE ENVIRONMENT为Production时关闭swagger 但是往往我们需要将api
  • 新手树莓派4B安装Supervised+Home Assistant及问题解决

    测试平台 xff1a 树莓派4B 4G 系统版本 xff1a Raspberry Pi OS with desktop and recommended software Release date September 22nd 2022 Sy
  • 无人机高精度定位之——RTK与PPK概念扫盲

    无人机高精度定位之 RTK与PPK概念扫盲 无人机的兴起 xff0c 已经让很多行业激动不已 xff0c 如电力巡检 应急救援 测绘 农业植保等行业 而随着高精度卫星导航技术的加持 xff0c 让无人机定位更加高效 安全 灵活 xff0c
  • 数据结构与算法--01数组:为什么大多编程语言中数组从0开始编号?

    数据结构与算法 01数组 xff1a 为什么很多编程语言中数组从0开始编号 xff1f 一 数组特性二 数组访问越界问题三 数组与容器四 回到开篇五 总结 一 数组特性 1 数组本质上是一种线性表数据结构 xff0c 用一组连续的内存空间来
  • 数据结构与算法--02链表-如何轻松写出链表代码

    数据结构与算法 02链表 如何轻松写出链表代码 写好链表并不是件容易的事情 xff0c 尤其是一些复杂的链表操作 xff0c 如链表反转 有序链表合并等等 即使能够写出代码 xff0c 但及其容易出错 所以付出一定量的精力是前提条件 xff
  • QT for Windows安装配置总结及采坑问题汇总

    QT for Windows安装配置总结及采坑问题汇总 一 安装包下载二 安装三 Qt Creator配置四 遇到的问题 一 安装包下载 1 Qt官方下载地址 xff1a http download qt io archive qt xff
  • IOS系统历届版本大回顾(<iOS7)

    APPLE xff0c 一种常见的水果 xff0c 但在人类的进化史上扮演了2次拯救世界的角色 第一次是在1666年一个夏末的傍晚 xff0c 在英格兰林肯郡的乌尔斯索普 xff0c 当一个年轻人坐在树下 xff0c 埋头读书的时候 xff
  • 总结-虚拟机安装OS X系统步骤及遇到的问题

    一 安装步骤 1 创建一个文件夹 xff0c 用于向虚拟机系统共享文件 xff0c 如 xff1a work 2 下载好所需的安装包 xff1a a VMware虚拟机安装包 xff08 包含unlocker软件 xff0c 用于解锁VMw

随机推荐

  • Git-回退到指定版本

    Git 回退到指定版本 1 方法一 xff1a git reset2 方法二 xff1a git commit amend 1 方法一 xff1a git reset 直接回退到指定版本 xff0c 目标版本之后的提交将被删除 情况一 xf
  • 我的2011--快乐最重要

    呵呵 xff0c 听着郭德纲和于谦老师的相声 xff0c 开始写这篇文章 xff0c 刚毕业不到六个月 xff0c 就换了一份工作 xff0c 很多事情都在意料之外 xff0c 很多事情又在意料之中 xff0c 总之 xff0c 以后回忆到
  • 如何在github的wiki中添加新的图片

    本文简单介绍在github的wiki中添加新的图片对方法 在github的wiki中 xff0c 可以展现图片 xff0c 可是 xff0c 怎么添加图片 xff0c 从网页上展示的信息来看 xff0c 不是很清楚 添加图片 xff0c 基
  • iOS-AppStore上传应用更新之——Xcode上传ipa

    iOS AppStore上传应用更新之 Xcode上传ipa 一 App Store Connect添加新版本配置二 Xcode验证IPA有效性三 生成IPA包 xff0c 通过xcode直接上传至AppStore四 注意事项 好久没有打包
  • CSDN博客搬家至掘金

    博客搬家说明 xff1a 作为一名程序员 xff0c 掘金是目前最适合我们的一个平台 xff0c 所以决定将CSDN博客搬迁至掘金 xff01 CSDN是我第一个接触的博客平台 xff0c 你将成为我最美的回忆 xff0c 永远爱你 xff
  • 机器人学习之项目- Project1 : Go Chase it!(一)

    1 项目简介 任务概述 在这个项目中 xff0c 在catkin ws src中创建两个ROS包 drive bot和ball chaser 下面是设计机器人的步骤 xff0c 把它安置在一个设定的世界里 xff0c 并编程让它追逐白色的球
  • R6002-floating point not loaded 的问题解决方法

    最近项目的要计算浮点数据 xff0c 为了调试方便 xff0c 输出计算结果值到DEBUG信息 xff0c 结果却出现 R6002 错误 Google了一下 xff0c MSDN上对于R6002的描述信息是 xff1a 错误消息 未加载浮点
  • Eclipse 创建spring Boot 项目pom.xml报错处理

    1 最首先检查版本问题 xff0c 需要的话更新maven插件 点击help Install New Software Work with输入如下地址 https otto takari io content sites m2e extra
  • python如何查看函数或者模块的源代码

    查看函数的源代码 xff1a 一般来说 xff0c 一个python函数会自带一个 code 变量 xff0c 其中包含了该函数源码的文件路径 以 os path exists 函数为例 xff0c 打印它的源代码文件位置 xff1a im
  • SUN RGB-D数据集的理解

    SUN RGB D数据集是普灵斯顿大学的 Vision amp Robotics Group 公开的一个有关场景理解的数据集 官方介绍在此 xff0c 其中有视频介绍 视频介绍已经很详细了 xff0c 建议先看懂视频 此博客仅仅列出个人认为
  • ORB_SLAM2--源码编译

    前言 学习ORB SLAM2 xff0c 从编译源码开始 ORB SLAM2的github地址 https github com raulmur ORB SLAM2 一 准备工作 1 安装依赖库 sudo apt install cmake
  • ORB_SLAM2的单目SLAM提高关键帧的个数

    一 前言 最近在结合ORB SLAM2和Map2DFusion xff0c 来做无人机航拍视频建图 xff0c 基本完成了pipeline xff0c 但发现出来的效果没有Map2DFusion官方的效果好 xff08 第一张图是我自己处理
  • fmt报错

    在编译Map2DFusion时 xff0c 遇到fmt报错的问题 xff1a home user01 ZhengJiafang Map2DFusion src Map2D cpp 23 usr local include sophus co
  • android4.0新控件Switch方法解析

    就是很像开关的那种控件 xff0c 它只有两个状态 xff1a on和off xff1a 在IOS中 xff0c 有个UISwitch控件 xff0c 其效果图 xff0c 如下 xff1a 在android4 0里面 xff0c 添加了一
  • 视觉SLAM融合GPS尝试

    一 前言 最近在做无人机建图的相关工作 xff0c 基本的方案是ORB SLAM2 43 Map2DFusion 在调试好代码后 xff0c 我利用大疆精灵4在附近的一个公园进行算法测试 xff0c 得到的效果图如下 xff1a 但在一些细
  • python读取与保存图片的exif信息

    图片的exif文件格式中保存了很多信息 xff0c 比如GPS经纬度 xff0c 高度 xff0c 焦距等信息 在图片的属性中可以看到这些信息 xff1a 我们可以使用python来进行exif数据的读取和保存 1 首先安装piexif p
  • ROS深度图转化为点云

    自己编写C 43 43 的ROS代码 xff0c 订阅D435i深度图像 xff0c 转化为点云数据 xff0c 并发布出去 说明 xff1a D435i本身就可以输出点云 xff0c 不需要自己编写代码 本博客的目的是通过自己编写深度图转
  • 大疆校招测评题--循环赛问题

    笔者在2022 7参加了大疆的测评题 其中有道循环赛问题 xff0c 记录下解题思路 循环赛问题 六名选手A B C D E F进行循环赛 每两名选手间比赛一次 xff0c 每名选手每天比赛一场 五天内完成循环赛 已知 xff1a 第一天C
  • Ubuntu22.04安装libudev-dev时的Bug

    新安装了Ubuntu22 04 xff0c 然后安装libudev dev xff1a sudo apt install libudev dev 发现了非常奇怪的事情 xff1a 正在读取软件包列表 完成 正在分析软件包的依赖关系树 完成
  • python爬虫教程——科研向

    引言 在科研中 xff0c 有时需要爬取网站上的文本数据 xff0c 用于统计分析 xff0c 或是制作机器学习所用的数据集 举个例子 xff0c 假如我们需要在世界野生鸟类声音网XenoCanto中 xff0c 爬取网站上的鸟类声音标签信