投稿问答最小化  关闭

万维书刊APP下载

爬虫应用 | 批量获取植物名录和性状数据(二)

2022/3/25 14:44:20  阅读:456 发布者:chichi77

在上一篇推文爬虫应用 | 批量获取植物名录和性状数据(一)中,主要存在两个问题:

1、当页面数为1时,程序无法正常提取数据,最终只获取到了1.1万个物种名录;

2、程序只能提取物种名录,对于研究中常用的物种分布区、最大树高等数据却无法提取。

要获取Useful Tropical Plants Database中的最大树高和物种分布区信息,我们沿用之前批量获取《中国植物志》和《种子信息数据库》的基本思路:1)首先获取数据库中物种名录;2)然后根据物种名录,逐个在网站查询并提取各物种的分布区、最大树高等数据。

1. The Useful Tropical Plants Database

第一步:获取物种名录

为了获取Useful Tropical Plants Database网站的植物名录,我们对之前的程序进行了修改,下面的程序可以完整的获取该网站记录的12727种植物(可以参考之前的方法二对程序进行简化):

from bs4 import BeautifulSoup ## 用于解析网页

import string  ## 生成字符串

import requests  ## 用于访问网页链接

import time  ## 设置延时器,模拟用户点击时间间隔

### 设置浏览器头部信息

# 通过该头部信息,web服务器可以判断到当前HTTP请求的客户端浏览器类别

headers = {

    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36"

}

#### 通过翻阅所有网页,我们发现有两处相同点和两处不同点,提取出相同点

### 网页相同部分1

prefix1 ="http://tropical.theferns.info/letter-index.php?letter="

### 网页相同部分2

prefix2 ="&amount=100&pageno="

### 生成字母列表,用于逐个查询

letters=list(string.ascii_uppercase) ### 生成所有大写字母

### 生成空数据框,用于存放数据

list=[]

## 由于不同字母之间网页数不同,需要先提取页面数,然后逐页提取数据

### 根据页面数设置范围

for i in range(0, len(letters),1):

    url1= prefix1 + letters[i] ### 生成每个字母的网页

    html = requests.get(url1, headers=headers) ## 将网页链接赋给requests.get()函数——申请访问

    ### 打开网页后,用BeautifulSoup()函数对网页内容进行解析

    soup = BeautifulSoup(html.content, "html5lib")

    ### 关键步骤——提取网页中特定的内容(表格信息)

    ## 查找所有p的节点

    pnodes = soup.find_all('p') ## 提取所有行的数据,有两列

    ## 提取页面数所在的位置

    text = pnodes[3]  ## 提取页面数所在的节信息,用于后续提取页面数

    len = text.get_text()  ## 提取包含页面数的文本信息

    ### 通过查看页面数所在位置,提取页面数(可以用其他方法提取)

    page = len[17:19] ## 提取页面数——字符串

    ## 得到页面数的值,用于构建网址

    pages=int(page)

    

    ### 当页面数为1时,不进行翻页操作

    if pages<=1:

        url = url1

        ## 根据生成的网址访问网页

        html = requests.get(url, headers=headers)  ## 将网页链接赋给requests.get()函数——申请访问

        # 打开网页后,用BeautifulSoup()函数对网页内容进行解析

        soup = BeautifulSoup(html.content, "html5lib")

        # 关键步骤——提取网页中特定的内容(表格信息)

        table = soup.find('table')  ## 表格

        td_nodes = table.find_all(class_='ANCHOR')  ### 只提取拉丁名

        for res in td_nodes:

            result = res.get_text()

            # sheet.append(result)

            list.append(result)

    ### 当页面数超过1时,遍历每一页

    else:

        for n in range(0, pages * 100, 100):

            url = url1 + prefix2 + str(n)

            ## 根据生成的网址访问网页

            html = requests.get(url, headers=headers)  ## 将网页链接赋给requests.get()函数——申请访问

            # 打开网页后,用BeautifulSoup()函数对网页内容进行解析

            soup = BeautifulSoup(html.content, "html5lib")

            ### 关键步骤——提取网页中特定的内容(表格信息)

            table = soup.find('table')  ## 表格

            td_nodes = table.find_all(class_='ANCHOR')  ### 只提取拉丁名

            for res in td_nodes:

               result = res.get_text()

               # sheet.append(result)

               list.append(result)

        time.sleep(2)  ### 间歇2

### 将结果导出为txt文件

with open('data.txt','w') as f:

    f.write('\n'.join(list))

第二步:获取物种其他信息(以最大树高为例)

在提取到Useful Tropical Plants Database网站的物种名录后,通过以下程序逐个查询并提取最大树高数据(分布区、生活型以及传粉方式等信息的提取方法类似):

from bs4 import BeautifulSoup ## 用于爬虫

import pandas as pd  ## 用于读取数据

import requests  ## 用于访问网页链接

import time  ## 设置延时器,模拟用户点击时间间隔

## 打开并解析网页get_url函数

def get_url(url):  ## url由用户提供,放置在main程序中

    # data = requests.get(url, headers=headers)

    html = requests.get(url, headers=headers)

    # 使用html5lib 容错率较高——html5lib方式

    soup = BeautifulSoup(html.content,"html5lib")

    ## htmlrequests对象,无法用BeautifulSoup解析,可以在html后面加上content,html.content

    return soup

### 提取物种信息的gain_data函数

def gain_data(soup):

    table = soup.find('tbody')  ## 找到表格

    # trs= table.find_all("tr") ## 查阅所有的行

    tds= table.find_all("td") ## 查阅所有列

    

     ### 将表格中所有结果存入列表中

     ui = []  ## 建立一个空列表

     for td in tds:

        text = td.get_text()

        ui.append(text)

        

        ###  筛选出需要的数据

     for i in range(0, len(ui), 1):

        name = ui[i]

        if name == "Height":

           res = ui[i + 1]

           result = res.replace(' ', '')  ## 去除字符串中的空格

    return result ## 返回结果,不打印

##### 主程序——提取所有物种的最大树高数据

### 生成空列表

list1=[]

### 调用网页范围、解析和数据

if __name__ == '__main__':

    ## 读取数据并合成网页链接

    data= pd.read_excel(".\plants.xlsx")  ### 热带植物名录数据存放于D:/Documents/plants.xlsx

    dat=data.values  ## 提取data中的内容

    partitions=list(map(list, zip(*dat))) ## 对数据进行转置,此时数据会变成双中括号的格式[["a","b"]],需要转换成单个中括号格式,partitions[0]

    # print(partitions) ## 此时将数据框数据转为列表数据,用于后面逐个提取物种名

    prefix ="http://tropical.theferns.info/viewtropical.php?id="  ## 热带植物数据库按物种查询网址前半部分

    for partition in partitions[0]:

        url = prefix + partition  ## 生成完成的链接,并赋值给url

        soup = get_url(url)  ## 调用get_url打开网页

        result = gain_data(soup)  ## 提取需要的物种信息

        result = partition +" "+ result ## 将结果存入列表中

        list1.append(result) ## 将提取的结果存入list1列表中

        time.sleep(2)  ### 间歇2

### 将结果导出为txt文件

with open('data.txt','w') as f:

    f.write('\n'.join(list1))

 

如有侵权,请联系本站删除!

  • 万维QQ投稿交流群    招募志愿者

    版权所有 Copyright@2009-2015豫ICP证合字09037080号

     纯自助论文投稿平台    E-mail:eshukan@163.com