网页表格抓取(爬虫所要通用的表格函数应对方法,对你非常有帮助)
优采云 发布时间: 2021-10-09 16:44网页表格抓取(爬虫所要通用的表格函数应对方法,对你非常有帮助)
如果你的爬虫想要爬取的内容存在于页面的table标签中,那么本文探讨的方法对你很有帮助。
下面两个网址有非常规范的表格数据
前者是北京500强名单,后者是中国500强名单
对于常规爬取,需要对页面进行分析,准确找到这部分内容的标签位置,然后进行定点爬取。分析了几个页面,发现这些表中的数据非常相似。
它们存储在 table 标记中。第一个tr是第一行的标题,数据内容从第二个tr开始。
排名
公司名称(中英文)
营业收入(百万美元)
2
国家电网公司(STATE GRID)
348903.1
3
中国石油化工集团公司(SINOPEC GROUP)
326953
4
中国石油天然气集团公司(CHINA NATIONAL PETROLEUM)
326007.6
既然都长得一样,何不写一个通用的表单爬取功能,这样当你遇到这种页面时,可以快速爬取。之所以不写一般的表单爬虫,是因为不同的页面获取方式不同,但是只要获取到html,其余的分析提取过程都是一样的。
如果你想让一个函数处理所有情况,你需要对表格有特殊的理解,这样这个函数才能覆盖大部分情况。至于一些特殊的页面,则不在此功能范围之内。
第一个tr是标题行,内部标签可以是th或td。对于tbody中的tr,内部是td。编写程序时应注意这一点。在获取td内容时,我只关心实际的文本内容。至于加粗的标签或者链接,不是我想要的。因此,代码中只需要提取td下的文本内容即可。
思路确定了,代码就容易写了
import pprint
import requests
from lxml import etree
def get_table_from_html(html):
tree = etree.HTML(html)
# 寻找所有的table标签
table_lst = tree.xpath("//table")
table_data_lst = []
for table in table_lst:
table_data_lst.append(get_table(table))
return table_data_lst
def get_table(table_ele):
"""
获取table数据
:param table_ele:
:return:
"""
tr_lst = table_ele.xpath(".//tr")
# 第一行通常来说都是标题
title_data = get_title(tr_lst[0])
# 第一行后面都是数据
data = get_data(tr_lst[1:])
return {
'title': title_data,
'data': data
}
def get_title(tr_ele):
"""
获取标题
标题可能用th 标签,也可能用td标签
:param tr_ele:
:return:
"""
# 先寻找th标签
title_lst = get_tr_data_by_tag(tr_ele, 'th')
if not title_lst:
title_lst = get_tr_data_by_tag(tr_ele, 'td')
return title_lst
def get_data(tr_lst):
"""
获取数据
:param tr_lst:
:return:
"""
datas = []
for tr in tr_lst:
tr_data = get_tr_data_by_tag(tr, 'td')
datas.append(tr_data)
return datas
def get_tr_data_by_tag(tr, tag):
"""
获取一行数据
:param tr:
:param tag:
:return:
"""
datas = []
nodes = tr.xpath(".//{tag}".format(tag=tag))
for node in nodes:
text = node.xpath('string(.)').strip()
datas.append(text)
return datas
def get_html(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
}
res = requests.get(url, headers=headers)
res.encoding = 'utf-8'
return res.text
def run():
url = 'https://baike.baidu.com/item/%E4%B8%AD%E5%9B%BD%E4%BC%81%E4%B8%9A500%E5%BC%BA/5542706?fr=aladdin'
# url = "https://www.phb123.com/qiye/35109.html"
html = get_html(url)
table_lst = get_table_from_html(html)
pprint.pprint(table_lst)
if __name__ == '__main__':
run()
目前只有少数几个网页被用于测试。如果遇到无法通过此方法准确抓取的页面,可以给我留言,我会根据页面内容改进此表单的抓取方法