把大象装进冰箱里需要3步,那么用python做网络爬虫呢?
用python做网络爬虫,也可以分3步:
今天,主要是想谈一谈第2步,也就是如何进行数据的提取。
一般而言,3种提取数据的方法中,re速度最快,但设计正则表达式规则相对复杂;xpath速度其次,其设计规则一定程度上类似有些类似于从sql中查询数据,难度居中;bs4速度较慢,但理解简单实现也较为容易。
在具体的爬虫数据提取时,可能并不能仅用单一的提取方法,综合运用可能效果更好。例如,爬取到某网页的源码格式如下:
<div class="intro">
<dl>
<dt><a href="************" target="_blank"><h3>************</h3></a></dt>
<dd class="slt"><a href="****#" target="_blank"><img src="****" alt="************" border="0/"><br>****</a></dd>
<dd> 执业许可证号:************</dd>
<dd> 住所:************</dd>
<dd> 联络地址:************</dd>
<dd> 电话:************</dd>
<dd> 传真:************</dd>
<dd> 网站:<a href="************#" target="_blank">************</a></dd>
<dd> 负责人:
<a href="************" target="_blank">****</a>
</dd>
<dd> 组织形式:****</dd>
<dd> 主管机关:****</dd>
<dd> 批准日期:****</dd>
<dd> 执业状态:****</dd>
</dl>
<table width="100%" border="0" cellpadding="0" cellspacing="2" bgcolor="#FFFFFF">
<tbody><tr>
<td width="15%" align="right" bgcolor="#f2f2f2">********</td>
<td width="85%" bgcolor="#f2f2f2" class="team">
<a href="************" target="_blank">****</a>
</td>
</tr>
<tr>
<td width="15%" align="right" bgcolor="#f2f2f2">********</td>
<td width="85%" bgcolor="#f2f2f2" class="team">
<a href="********" target="_blank">****</a>
<a href="********" target="_blank">****</a>
<a href="********" target="_blank">****</a>
<a href="********" target="_blank">****</a>
<a href="********" target="_blank">****</a>
</td>
</tr>
</tbody></table>
</div>
源码中的所有文字信息即为要提取的字段数据,经分析发现源码2部分信息特点不一:
<div class="intro">
<dl>
--基础信息:字段数目固定
</dl>
<table width="100%" border="0" cellpadding="0" cellspacing="2" bgcolor="#FFFFFF">
<tbody><tr>
<td width="15%" align="right" bgcolor="#f2f2f2"> </td>
<td width="85%" bgcolor="#f2f2f2" class="team">
--人员信息1:字段数目可变
</td>
</tr>
<tr>
<td width="15%" align="right" bgcolor="#f2f2f2"> </td>
<td width="85%" bgcolor="#f2f2f2" class="team">
--人员信息2:字段数目可变
</td>
</tr>
</tbody></table>
</div>
基于此,
pattern = r'<div class="intro">.*?alt="(.*?)" .*?执业许可证号:(.*?)</dd>.*?住所:(.*?)</dd>.*?联络地址:(.*?)</dd>.*?电话:(.*?)</dd>.*?传真:(.*?)</dd>.*?网站:<a href="(.*?)".*?负责人:.*?>(.*?)</a>.*?组织形式:(.*?)</dd>.*?主管机关:(.*?)</dd>.*?批准日期:(.*?)</dd>.*?执业状态:(.*?)</dd>'
lawers = element.xpath("//table/tr//a/text()")
结论:re和xpath作为爬虫信息提取的2种常用方法,各有利弊不分伯仲,可根据各自特点灵活选用,其中对于规律性比较强的,优先选用re提取数据;而当字段数目或者信息规则不确定时,则可以设计xpath提取。
另外:在将lxml.etree._Element对象转化为string对象时,还踩了一个坑,即直接tostring()后,会出现格式混乱即中文无法显示的问题,此时仅链式增加.decode()仅能解决格式混乱的问题,中文字符仍然会用&#xxxxx编码。此时,解决办法是在tostring()中明确编码类型,尔后再decode()可有效解决这一问题。
content = etree.tostring(content).decode('utf-8')
△ tostring()直接解码中文显示为编码
content = etree.tostring(content, encoding = "utf-8").decode('utf-8')
△ tostring()指定编码后再解码中文显示正确