前段时间,一朋友让我做个小脚本,抓一下某C2C商城上竞争对手的销售/价格数据,好让他可以实时调整自己的营销策略。自己之前也有过写爬虫抓某宝数据的经历,实现的问题不大,于是就答应了。初步想法是利用pyhton中的urllib.request和re两个lib(本文示例用的是Pyhton 3.4 ,2.x的请自行切换),外加上其他的统计分析功能的话,最多两个晚上(白天要工作)可以搞定。实际上做的过程中,遇到了两个主要困难:
(1)电商网站对于交易数据的保护很好。小爬虫动不动就会被ban掉或者采用一些其他的保护措施使得其无法正常采集所需的数据,需要添加额外的代码处理各种虐心的情况;
(2)正则表达式实在是难写,而且很复杂和很难维护。于是自己也思考有没有其他的解决方案——本文就是对其中一解决方案的初步介绍。
 
一开始想到的当然是著名的第三方库Beautifulsoup(作为一个广东男人,我习惯把它称为”靓汤“)。这个库很强大,但正因为它强大,需要一点学习时间而我需要快点上手,于是只好日后再学(到时再写一篇Beautifulsoup学习总结)。权衡以后,最后目光转向了Python Standard Library中的html.parser。
 
html.parser是一个非常简单和实用的库,它的核心是HTMLParser类。从源码来看,它内部封装了一系列regular expression。工作的流程是:当你feed给它一个类似HTML格式的字符串时,它会调用goahead方法向前迭代各个标签,并调用对应的parse_xxxx方法提取start_tag, tag, attrs data comment和end_tag等等标签信息和数据,然后调用对应的方法对这些抽取出来的内容进行处理。整个HTMLParser的大致结构如下图所示:
 
 
 
可以发现,处理开始标签(handle_starttag)、结束标签(handle_endtag)和处理数据(handle_data)等处理函数在HTMLParser里是没有实现的(pass),这需要我们继承HTMLParser这个类的并覆盖这些方法。详细可以参阅python文档,这里重点介绍几个常用的方法:
 
  1. feed(data):主要用于接受带html标签的str,当调用这个方法时并提供相应的data时,整个实例(instance)开始执行,结束执行close()。
  2. handle_starttag(tag, attrs): 这个方法接收Parse_starttag返回的tag和attrs,并进行处理,处理方式通常由使用者进行覆盖,本身为空。例如,连接的start tag是<a>,那么对应的参数tag=’a’(小写)。attrs是start tag <>中的属性,以元组形式(name, value)返回(所有这些内容都是小写)。例如,对于<A HREF="http://www.baidu.com“>,那么内部调用形式为:handle_starttag(’a’,[(‘href’,’http://www.baidu.com)]).
  3. handle_endtag(tag):跟上述一样,只是处理的是结束标签,也就是以</开头的标签。
  4. handle_data(data):处理的是网页的数据,也就是开始标签和结束标签之间的内容。例如:<script>...</script>的省略号内容
  5. reset():将实例重置,包括作为参数输入的数据进行清空。
 
举个例子吧。例如我们有以下一堆带HTML标签的数据,

     【金冠现货/全色/顶配版】Xiaomi/小米 小米note移动联通4G手机
   </h3>
   <p class="tb-subtitle">
 【购机即送布丁套+高清贴膜+线控耳机+剪卡器+电影支架等等,套餐更多豪礼更优惠】    【购机即送布丁套+高清贴膜+线控耳机+剪卡器+电影支架等等,套餐更多豪礼更优惠】    【金冠信誉+顺丰包邮+全国联保---多重保障】
 </p>
   <div id="J_TEditItem" class="tb-editor-menu"></div>
 </div>
<h3 class="tb-main-title" data-title="【现货增强/标准】MIUI/小米 红米手机2红米2移动联通电信4G双卡">
     【现货增强/标准】MIUI/小米 红米手机2红米2移动联通电信4G双卡
   </h3>
   <p class="tb-subtitle">
 [红米手机2代颜色版本较多,请亲们阅读购买说明按需选购---感谢光临] 【金皇冠信誉小米手机集市销量第一】【购买套餐送高清钢化膜+线控通话耳机+ 剪卡器(含还原卡托)+ 防辐射贴+专用高清贴膜+ 擦机布+ 耳机绕线器+手机电影支架+ 一年延保服务+ 默认享受顺丰包邮 !
 </p>
   <div id="J_TEditItem" class="tb-editor-menu"></div>
 </div>

很明显,这里面包含了两台手机,我们的目标是提取两个手机的名字出来。
 
由于当我们feed这个html到HTMLParser中后,他们所有的标签都迭代,如果需要它只提取我们需要的数据时,我们需要设置当handle_starttag遇到那个标签和属性时,才调用handle_data并print出我们的结果,这个时候我们可以使用一个flg作为判定,代码如下:
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#定义一个MyParser继承自HTMLParser
class MyParser(HTMLParser):
    re=[]#放置结果
    flg=0#标志,用以标记是否找到我们需要的标签
    def handle_starttag(self, tag, attrs):
        if tag=='h3':#目标标签
            for attr in attrs:
                if attr[0]=='class' and attr[1]=='tb-main-title':#目标标签具有的属性
                    self.flg=1#符合条件则将标志设置为1
                    break
        else:
            pass
  
    def handle_data(self, data):
        if self.flg==1:
            self.re.append(data.strip())#如果标志为我们需要的标志,则将数据添加到列表中
            self.flg=0#重置标志,进行下次迭代
        else:
            pass
 
 
my=MyParser()
my.feed(html)
 
运行结果如下,达到了我们的预期:


 
上面只是HTMLParser一个非常简单的应用,但却可以反应了HTMLParser这个类的一些特质。有了这些基本的认识后,我们就可以将相关功能进行扩展,从而形成一个标准的爬虫了。下次,我们将利用相关的知识,构建一个基本的网络爬虫,敬请期待哦。
 
--------------------------------------------------
本文为作者原创文章,转摘请注明出处:@Datazen

PYTHON HTML.PARSER库学习小结--转载的更多相关文章

  1. Python html.parser库学习小结

    分类路径:/Datazen/DataMining/Crawler/   前段时间,一朋友让我做个小脚本,抓一下某C2C商城上竞争对手的销售/价格数据,好让他可以实时调整自己的营销策略.自己之前也有过写 ...

  2. python爬虫解析库学习

    一.xpath库使用: 1.基本规则: 2.将文件转为HTML对象: html = etree.parse('./test.html', etree.HTMLParser()) result = et ...

  3. Python之matplotlib库学习

    matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图.而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中. 它的文档相当完备, ...

  4. python 之Requests库学习笔记

    1.    Requests库安装 Windows平台安装说明: 直接以管理员身份打开cmd运行界面,使用pip管理工具进行requests库的安装. 具体安装命令如下: >pip instal ...

  5. Python之matplotlib库学习:实现数据可视化

    1. 安装和文档 pip install matplotlib 官方文档 为了方便显示图像,还使用了ipython qtconsole方便显示.具体怎么弄网上搜一下就很多教程了. pyplot模块是提 ...

  6. 基于Windows平台的Python多线程及多进程学习小结

    python多线程及多进程对于不同平台有不同的工具(platform-specific tools),如os.fork仅在Unix上可用,而windows不可用,该文仅针对windows平台可用的工具 ...

  7. Python之Pandas库学习(二):数据读写

    1. I/O API工具 读取函数 写入函数 read_csv to_csv read_excel to_excel read_hdf to_hdf read_sql to_sql read_json ...

  8. Python之Pandas库学习(一):简介

    官方文档 1. 安装Pandas windos下cmd:pip install pandas 导入pandas包:import pandas as pd 2. Series对象 带索引的一维数组 创建 ...

  9. python的pandas库学习笔记

    导入: import pandas as pd from pandas import Series,DataFrame 1.两个主要数据结构:Series和DataFrame (1)Series是一种 ...

随机推荐

  1. hdu1166敌兵布阵&&hdu1754I Hate It(线段树入门)

    单点更新是最最基础的线段树,只更新叶子节点,然后把信息用pushup这个函数更新上来. http://acm.hdu.edu.cn/showproblem.php?pid=1166 update单点更 ...

  2. Chrome Input框老是有输入记录的终极解决方案

    尤其是日期框,输入记录都挡住日期弹框了. 浏览器地址栏输入: chrome://settings/autofill,按钮关掉就可以了.

  3. QPixmap 显示大小

    size picSize(600,400); //将pixmap缩放成picSize大小然后保存在scaledPixmap中 按比例缩放: QPixmap scaledPixmap = pixmap. ...

  4. 问题排查之'org.apache.rocketmq.spring.starter.core.RocketMQTemplate' that could not be found.- Bean method 'rocketMQTemplate' in 'RocketMQAutoConfiguration' not loaded.

    背景 今天将一个SpringBoot项目的配置参数从原有的.yml文件迁移到Apollo后,启动报错“Bean method 'rocketMQTemplate' in 'RocketMQAutoCo ...

  5. hdu3511 Prison Break 圆的扫描线

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=3511 题目: Prison Break Time Limit: 10000/5000 MS ( ...

  6. ac1008

    这题说的是 给了n个点在圆 上 然后 i连 i+2 从i+2 开始连 i+4  然后 这样一直到某个点 已经被连过为止   如果还有的没有被连过 就从那个点开始 连 按照上面的规则 当 N大于6 的时 ...

  7. [转]Mac Appium环境安装

    原文:https://blog.csdn.net/dongqiushan/article/details/53326518 1.安装JDK; 2.安装Android SDK; 3.安装brew; 4. ...

  8. 关于Context []startup failed due to previous errors

    文章转自:http://blog.sina.com.cn/s/blog_49b4a1f10100q93e.html 框架搭建好后,启动服务器出现如下的信息: log4j:WARN No appende ...

  9. Linux基础命令---swapoff

    swapoff 关闭交换分区,同时可以刷新交换分区的缓存.关闭交换分区后,使用free指令查看内存,swap数值会减少.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE. ...

  10. 神州行省内流量套餐6元500M申请,发送BLSN6到10086即可

    神州行流量套餐,神州行省内流量套餐6元500M申请,发送BLSN6到10086即可申请开通专属流量包,比全国5元30M划算多了4G全国流量套餐 5元/30M 10元/100M 20元/300M 30元 ...