前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用re和xpath进行爬虫信息提取

用re和xpath进行爬虫信息提取

作者头像
luanhz
发布2020-03-31 17:14:10
7580
发布2020-03-31 17:14:10
举报
文章被收录于专栏:小数志

把大象装进冰箱里需要3步,那么用python做网络爬虫呢?

用python做网络爬虫,也可以分3步:

  • 通过各种手段获取网络响应,得到网页源码,其中源码包含想要爬取的各种数据,例如requests、urllib、selenium等,具体方法根据目标网页反爬措施而异;
  • 在获得的网页源码中提取数据,常用方法包括re、Xpath、Bs4等;
  • 对提取的数据进行处理保存,例如写入文件(.csv,.txt等等)或者存储数据库等。

今天,主要是想谈一谈第2步,也就是如何进行数据的提取。

一般而言,3种提取数据的方法中,re速度最快,但设计正则表达式规则相对复杂;xpath速度其次,其设计规则一定程度上类似有些类似于从sql中查询数据,难度居中;bs4速度较慢,但理解简单实现也较为容易。

在具体的爬虫数据提取时,可能并不能仅用单一的提取方法,综合运用可能效果更好。例如,爬取到某网页的源码格式如下:

代码语言:javascript
复制
<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部分信息特点不一:

  • 在基础信息中,字段数目固定,且非常有规律,用正则提取效率最高;
  • 在人员信息1和2中,字段数目可变,不仅每个table块中信息条目可变,且人员信息1和2也可能可有可无,所以用正则表达式无法应对这种可变的情况,用xpath根据规则来提取效果可能更好。
代码语言:javascript
复制
<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>

基于此,

  • 针对基础信息,设计如下正则表达式可完美提取(信息不全时除外),
代码语言:javascript
复制
pattern = r'<div class="intro">.*?alt="(.*?)" .*?执业许可证号:(.*?)</dd>.*?住所:(.*?)</dd>.*?联络地址:(.*?)</dd>.*?电话:(.*?)</dd>.*?传真:(.*?)</dd>.*?网站:<a href="(.*?)".*?负责人:.*?>(.*?)</a>.*?组织形式:(.*?)</dd>.*?主管机关:(.*?)</dd>.*?批准日期:(.*?)</dd>.*?执业状态:(.*?)</dd>'
  • 针对人员信息1和2,设计xpath解析表达式,并加入条件判断,可有效提取2部分信息
代码语言:javascript
复制
lawers = element.xpath("//table/tr//a/text()")

结论:re和xpath作为爬虫信息提取的2种常用方法,各有利弊不分伯仲,可根据各自特点灵活选用,其中对于规律性比较强的,优先选用re提取数据;而当字段数目或者信息规则不确定时,则可以设计xpath提取。

另外:在将lxml.etree._Element对象转化为string对象时,还踩了一个坑,即直接tostring()后,会出现格式混乱即中文无法显示的问题,此时仅链式增加.decode()仅能解决格式混乱的问题,中文字符仍然会用&#xxxxx编码。此时,解决办法是在tostring()中明确编码类型,尔后再decode()可有效解决这一问题。

代码语言:javascript
复制
content = etree.tostring(content).decode('utf-8')

△ tostring()直接解码中文显示为编码

代码语言:javascript
复制
content = etree.tostring(content, encoding = "utf-8").decode('utf-8')

△ tostring()指定编码后再解码中文显示正确

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小数志 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档