这里是个人吐槽,可略过
不知道大家写爬虫的时候有没有遇到过这种情况,看到那种表格形式的数据,就很头疼,因为我们要一个一个地去解析他们。
在解析网页数据地时候,我本人比较喜欢用xpath,拿企查查为例,下面是我是小白的时候写的代码(太菜了)…
def get_the_information(company_url):
company_url = company_url
# print(company_url)
r = requests.get(company_url, headers=headers)
# print(r.text)
html = etree.HTML(r.text)
First_list = []
try:
company_name = html.xpath('//h1/text()')[0]
except Exception as e:
company_name = ''
# print(company_name)
try:
phone = html.xpath('//span[@class="cvlu"]/span[2]/text()')[0]
except Exception:
phone = '无'
# print(phone)
try:
date = html.xpath('//table[@class="ntable"]//tr[1]/td[@class=""][2]/text()')[0].replace('n', '').replace(' ',
'')
except Exception:
date = ''
# print(date)
try:
status = html.xpath('//table[@class="ntable"]//tr[1]/td[@class=""][1]/text()')[0].replace('n', '').replace(' ',
'')
except Exception as e:
status = '无'
# print(status)
try:
address = html.xpath('//table[@class="ntable"]//tr[8]/td/span/a/text()')[0].replace('n', '').replace(' ', '')
except Exception:
address = '无'
try:
Subscribed_capital = int(
html.xpath('//section[@id="Cominfo"]//table[@class="ntable"]//tr[2]/td[2]/text()')[0].replace('n',
'').replace(
' ', '').split('万')[0]) / 10000
# print(Subscribed_capital)
Paid_capital = int(
html.xpath('//section[@id="Cominfo"]//table[@class="ntable"]//tr[2]/td[4]/text()')[0].replace('n',
'').replace(
' ', '').split('万')[0]) / 10000
# print(Paid_capital)
except Exception:
pass
try:
Legal_representative = re.findall('<a href=".*?" class="bname"><h2 class="seo font-20">(.*?)</h2></a>', r.text)[
0]
except Exception:
Legal_representative = '无'
print(Legal_representative)
# print(Legal_representative)
unMain_HTML = html.xpath('//div[@id="employeeslist"]/table[@class="ntable ntable-odd"]//tr')
# print(unMain_HTML)
First_list.append(company_name)
First_list.append(phone)
First_list.append(date)
First_list.append(status)
First_list.append(address)
First_list.append(Subscribed_capital)
First_list.append(Paid_capital)
First_list.append(Legal_representative)
unMain_information = []
for html in unMain_HTML:
two_information = []
try:
name = html.xpath('td[2]//span[@class="seo font-14"]/text()')[0]
position = html.xpath('td[@class="text-center"]/text()')[0].replace('n', '').replace(' ', '')
two_information.append(name)
two_information.append(position)
unMain_information.append(two_information)
# print(two_information)
except Exception:
pass
# print(unMain_information)
Main_HTML = html.xpath('//div[@id="ChangelistTable"]//table[@class="ntable"]//tr')
Main_information = []
for html in Main_HTML:
One_informatin = []
Change_data = html.xpath('./td[2]/text()')[0]
Change_information = html.xpath('./td[3]/text()')[0].replace('n', '').replace(' ', '')
try:
Change_before = html.xpath('./td[4]//a/text()')[0].replace('n', '').replace(' ', '')
except Exception:
Change_before = ' '
try:
Change_after = html.xpath('./td[5]//a/text()')[0].replace('n', '').replace(' ', '')
except Exception:
Change_after = ' '
One_informatin.append(Change_data)
One_informatin.append(Change_information)
One_informatin.append(Change_before)
One_informatin.append(Change_after)
Main_information.append(One_informatin)
# for m in Main_information:
# print(m)
# print(First_list)
# print(unMain_information)
return First_list, unMain_information, Main_information
现在回头看我写的代码,简直不忍直视,这么一大坨,就为了解析一个表格(我淦)。
随着技术的沉淀,现在学到了很多有用的库,通过引用这些库,我的代码可以做到25行搞定这种网页表格(连带保存),下面就给大家分享一下我的方法!
第一步——导入用到的库
import requests
from lxml import etree
import pandas as pd
import numpy as np
第二步——请求数据
headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",}
url = 'https://www.qcc.com/firm/8c9f7ddc1a7bcee3d1f7676773fe9404.html'
s = requests.Session()
r = s.get(url, headers=headers)
第三步(关键)——找到<table标签
至于为什么找<table 标签,我解释一下,是因为我们需要使用到pandas库中的 read_html方法,它可以自动把网页源码代码种,table标签中的表格数据,转换成列表。
table标签的样式:
<table border="1">
<tr>
<th></th>
<th></th>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
拿企查查为例,我们在网页源代码种找到table标签的位置
下面我们要做的就是把table标签的源代码给爬下来
html = etree.HTML(r.text)
table = html.xpath('//section[@id="Cominfo"]/table[@class="ntable"]')[0]
div_str = etree.tostring(table)
第四步——使用read_html()
我们只需要把div_str 放到read_html()的第一个参数的位置,后面接上编码,让header=1(作用是让第一行数据当表头,否则会多出来一行数字),因为返回的是个列表,我们接收第一个即可
df = pd.read_html(div_str, encoding='utf8', header=1)[0]
print(df)
结果如下:
我们把它的值遍历一下看看是什么
for i in df.values:
print(i)
原来是这样的,跟网页中的表格格式基本一致,但是这并不是我们想要的形式,我们需要的是一个字典,是键值对。
此时我们就需要把这些表格处理一下了。
第五步——处理数据
这里可以观察到,每个列表的键和值都是紧挨的,而且第一个是键,第二个是值,有的列表会有很多重复值。并且列表的最后会有个‘nan’,我们需要把他去掉。
for i in df.values:
l = list(i[:-1])
l2 = list(set(l))
l2.sort(key=l.index)
print(l2)
此时的输出结果是这样的:
离成功又近了一步!
加下来要做的就是把表格中的数据,转换成键值对的形式,以便于我们存储为csv
这里我是用的是numpy中的列表分割,我把每个列表的元素以2为单位进行分割,得到若干小列表,然后字典的键就是列表的第一个值,字典的值就是列表的第二个值!
dict = {}
for i in df.values:
l = list(i[:-1])
l2 = list(set(l))
l2.sort(key=l.index)
arry_list = np.array_split(l2, len(l2) / 2)
for L in arry_list:
L = list(L)
dict[L[0]] = L[1]
print(dict)
输出结果如下:
第六步——保存成表格
在得到字典后,我们要做的就是把它转换成dataframe,再使用pd.to_csv(),保存到本地
具体操作如下:
data = pd.DataFrame(dict, index=['阿里巴巴'])
print(data)
data.to_csv('阿里.csv')
第七步——查收数据
整体代码如下:
import requests
from lxml import etree
import pandas as pd
import numpy as np
headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",}
url = 'https://www.qcc.com/firm/8c9f7ddc1a7bcee3d1f7676773fe9404.html'
s = requests.Session()
r = s.get(url, headers=headers)
html = etree.HTML(r.text)
table = html.xpath('//section[@id="Cominfo"]/table[@class="ntable"]')[0]
div_str = etree.tostring(table)
df = pd.read_html(div_str, encoding='utf8', header=1)[0]
dict = {}
for i in df.values:
l = list(i[:-1])
l2 = list(set(l))
l2.sort(key=l.index)
arry_list = np.array_split(l2, len(l2) / 2)
for L in arry_list:
L = list(L)
dict[L[0]] = L[1]
print(dict)
data = pd.DataFrame(dict, index=['阿里巴巴'])
print(data)
data.to_csv('阿里.csv')
注意事项:我们使用pandas和numpy得到的表格,需要使用list()强转一下,否则不能直接操作!
学到的话给博主点个关注哦~