背景
老师要求我们查找100种植物的信息,这里利用python爬取植物数据库。快速完成作业。
中国植物物种信息数据库
思路
查询数据
打开数据库,可以发现查询方式和百度类似。前面是查询网址,最后加上你输入的关键词,网站就会返回查询结果。那么可以利用python模拟浏览器,循环发送查询请求(只需要改变最后的一个关键词即可)。然后爬取数据。
“http://db.kib.ac.cn/CNFlora/SearchEngine.aspx?q=”+“樟”
利用BeautifulSoup库进行爬取,p1为每次查询的关键词,随函数输入。循环调用函数即可。
url='http://db.kib.ac.cn/CNFlora/SearchEngine.aspx?q='+str(p1)
r = session.get(url)
demo=r.text
soup=BeautifulSoup(demo,'html.parser')
存种属数据
返回的数据如下,首先先将科名与属名保存下来。根据浏览器开发者模式可以看到,数据都在“td”标签中。使用soup.find_all(‘td’)寻找所有的td标签,并保存对应的数据。如果有一些关键词没有查找到就存为NULL。以便后期处理。
soup=soup.find_all('td')
try:
K.append(soup[3].string+' '+soup[4].string.strip())
K.append(soup[1].string+' '+soup[2].string.strip())
except:
K.append('NULL')
K.append('NULL')
K.append('NULL')
K.append('NULL')
进入关键词下级目录
网页中点击红框中的链接就会跳转到下一级目录,显示该植物的详细信息。于是使用开发者模式进行查看,可以发现在a标签的href属性中保存着跳转链接。
使用soup[4].a[‘href’]获取链接,然后访问,即可跳转到植物的详细信息页。
#进入关键词详细目录
url='http://db.kib.ac.cn/CNFlora/'+soup[4].a['href']
r = session.get(url)
demo=r.text
soup=BeautifulSoup(demo,'html.parser')
存正文
正文存在span标签内,span id=“ContentPlaceHolder1_lbl_fulltext” ,且标签的id属性含有fulltext信息。
可以先找到所有的span标签,然后遍历寻找到id属性中含有fulltext的。最后保存信息即可。
a=soup.body.form.find_all('span')
for i in a:
try :
if('fulltext' in i['id']):
i=i.string.strip()
i=i.replace('\r', '')
i=i.replace('\n', '')
i=i.replace(',', ' ')
K.append(i)
break
except:
pass
代码
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 20 16:04:14 2020
@author: Administrator
"""
import os
import requests
from bs4 import BeautifulSoup
#爬取信息
def spider_transit(p1,K):
#修改session的header,假装自己是浏览器
user_agent = (
'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.11 (KHTML, like Gecko) '
'Chrome/20.0.1132.57 Safari/536.11'
)
session = requests.session()
session.headers['User-Agent'] = user_agent
#查询数据库
url='http://db.kib.ac.cn/CNFlora/SearchEngine.aspx?q='+str(p1)
r = session.get(url)
demo=r.text
soup=BeautifulSoup(demo,'html.parser')
#存科名和属名
soup=soup.find_all('td')
try:
K.append(soup[3].string+' '+soup[4].string.strip())
K.append(soup[1].string+' '+soup[2].string.strip())
except:
K.append('NULL')
K.append('NULL')
K.append('NULL')
K.append('NULL')
#进入关键词详细目录
url='http://db.kib.ac.cn/CNFlora/'+soup[4].a['href']
r = session.get(url)
demo=r.text
soup=BeautifulSoup(demo,'html.parser')
#存属
a=soup.body.form.find_all('a')
for i in a:
try :
if('SearchResult.aspx' in i['href'] and '属' in i.string):
K.append(i.string.strip())
break
except:
a=soup.body.form.find_all('li')
try :
if('active' in i['class'] and '属' in i.string):
K.append(i.string.strip())
break
except:
pass
if(len(K)<5):
K.append('NULL')
#存关键词正文
a=soup.body.form.find_all('span')
for i in a:
try :
if('fulltext' in i['id']):
i=i.string.strip()
i=i.replace('\r', '')
i=i.replace('\n', '')
i=i.replace(',', ' ')
K.append(i)
break
except:
pass
if(len(K)<6):
K.append('NULL')
return K
#轨迹信息存储为csv文件
def apitocsv(List):
if(List[5]=='NULL'):
fo = open('F:\日期\植物\\undata.csv','a+',encoding ='utf-8')
Str=''
for i in range(len(List)):
Str=Str+','+str(List[i])
Str=Str.strip(',')
fo.writelines(Str+'\n')
fo.close()
else:
fo = open('F:\日期\植物\\data.csv','a+',encoding ='utf-8')
Str=''
for i in range(len(List)):
Str=Str+','+str(List[i])
Str=Str.strip(',')
fo.writelines(Str+'\n')
fo.close()
def main():
num=1
D=[['樟树','荷花玉兰','茶花','Loropetalum%20chinense%20(R.%20Br.)%20Oliv.%20var.%20rubrum%20Yieh','玉兰','卫矛属','樱桃李','雪松','Trachycarpus fortunei','石楠','圆柏','剑麻','杜鹃花亚科','垂丝海棠','齿叶冬青','银杏属','龙柏','十大功劳','黄杨属','阔叶十大功劳']
,['桃(原变种)','桃花','冬青属','白车轴草','池杉','腊梅','蒲公英','樱花','石楠','小琴丝竹','迎春花','刺柏','苦苣菜']
,['紫藤']
,['兰香草','野豌豆','毛茛属','紫锦木','草海桐属','女贞属']
,['鸡爪槭','黄菖蒲','泽漆','野菊','白车轴草','刚竹','千屈菜属','五针松','石榴属']
,['霍州油菜','地挑花','蓟','黄鹤菜','细叶旱芹','附地菜','益母草','三叶草','繁缕属','青蒿','翻白草','老鹤草','猪殃殃','荠菜','樱花','葎草','桂花']
,['月季','女贞','栀子属','卫矛','水苦荬']
,['蓬纍','诸葛菜','鸢尾属']
,['落石','桑属','牛筋草','珠芽景天','天胡荽','白茅','刺槐','芭蕉属','夹竹桃属','石榴属','绞股蓝']
,['含笑','枸骨','老鹤草','悬铃木属','南苜蓿','麦蓝菜','鸡爪槭','罗汉松属','阔叶箬竹','龙爪槐','小蜡','蜀葵']
,['蛇莓','兰花草','栾树','无花果','紫茉莉属','臭鸡矢藤','打碗花','香椿','荆芥属']]
List=['ppt总种序','原始名称','植物名称','科名','属名','植物种的形态特征及地理分布记述','备注']
apitocsv(List)
for i in range(len(D)):
for j in range(len(D[i])):
List=[]
if(num<10):
num1='zzx00'+str(num)
elif(num<100):
num1='zzx0'+str(num)
else:
num1='zzx'+str(num)
List.append(num1)
List.append(D[i][j])
List=spider_transit(D[i][j],List)
num=num+1
apitocsv(List)
main()
存在的问题
正文中含有英文信息,不过英文和中文之间隔着‘\n’可以尝试利用split将其分割开。然后检测每个子序列第一个文字,如果是英文字母就删除,这样就可以保留所有的正文。
之所以不用正则,是因为中文正文中也含有一些英文术语不能直接一起删除。