【python数据抓取技术与实战】BeautifulSoup

中文翻译:美丽汤。光听听名字就觉得是一个很棒的工具。

言归正传,说说我们抓取的数据。其实返回的数据都是有结构化的。一般会遇到的三种结构化的返回数据,分别是HTML、XML和json。今天所介绍的BeautifulSoup就是python中处理HTML或XML的分析库,也就是说它能够解析这两种结构化文件。对于json的处理和分析,我们放到下一节再讲。

BeautifulSoup能做抽取数据,提供各类方法,可以方便的对文档进行搜索、抽取和修改。我们来看代码:

from bs4 import BeautifulSoup
with open('bydict_网上书店2.html','r',encoding='gbk') as f:
    bs=BeautifulSoup(f.read(),'lxml')
    a_lst=bs.find_all('a')
    for a in a_lst:
        if a.text!='':
            print(a.text.strip(),a['href'])
  • 这是我们在爬虫基础那一讲抓到的3个页面之一:‘bydict_网上书店2.html’,编码方式为gbk。
  • f.read()将读取文件的内容,结果是文件内文本字符串。
  • BeautifulSoup是一个类,返回的对象记作bs
  • a_lst=bs.find_all('a')可以找到页面中所有的a元素,并以列表的形式返回

以下是我们通过find_all方法查到的部分结果:

....
计算机 javascript:gotopage('计算机');
社科 javascript:gotopage('社科/人文');
经管 javascript:gotopage('经济管理');
少儿 javascript:gotopage('少儿');
电子技术 javascript:gotopage('电子技术');
通信 javascript:gotopage('通信与网络');
 /module/goods/wssd_content.jsp?bookid=<!--goodid-->
淘宝技术这十年 /module/goods/wssd_content.jsp?bookid=35948
高性能MySQL(第3版) /module/goods/wssd_content.jsp?bookid=35789
在你身边,为你设计:腾讯的用户.. /module/goods/wssd_content.jsp?bookid=34821
网络营销实战密码——策略、技巧.. /module/goods/wssd_content.jsp?bookid=35862
上帝之眼——旅行者的摄影书(全.. /module/goods/wssd_content.jsp?bookid=34653
我的环保行动书(1-4册)(全.. /module/goods/wssd_content.jsp?bookid=22452
向诸葛亮借智慧(含DVD光盘1.. /module/goods/wssd_content.jsp?bookid=21651
平衡计分卡导入与实施(修订版) /module/goods/wssd_content.jsp?bookid=27331
创作的灵感来自于生活 /xwxx/hdxx/2014-06-12/638.shtml
《香橼梦幻童话馆—透明怪兽... /xwxx/hdxx/2013-05-16/552.shtml
厦门海沧全民读书节校园捐赠 /xwxx/hdxx/2013-05-16/551.shtml
大师喜多俊之签售会完美结束 /xwxx/hdxx/2012-12-18/535.shtml
南亚!你的出国旅行第二站 /xwxx/hdxx/2012-10-24/518.shtml
知名摄影器材专家赵嘉巡讲活... /xwxx/hdxx/2012-04-12/465.shtml
快乐阅读行之爱上童话迷写作 /xwxx/hdxx/2012-04-09/462.shtml
电子社摄影群英汇——知名摄... /xwxx/hdxx/2012-02-29/451.shtml
计算机 #
社科 #
...

但是,如果我们的任务是提取图书的书名和链接,那我们只需要在if条件里加以下条件即可:

from bs4 import BeautifulSoup
with open('bydict_网上书店2.html','r',encoding='gbk') as f:
    bs=BeautifulSoup(f.read(),'lxml')
    a_lst=bs.find_all('a')
    for a in a_lst:
        if a.text!='' and 'wssd_content.jsp?bookid' in a['href']:
            print(a.text.strip(),a['href'])

运行结果如下所示:

摄影的骨头:高品质数码摄影流程.. ./wssd_content.jsp?bookid=36518
通往独立之路:摄影师生存手册(.. ./wssd_content.jsp?bookid=36519
 /module/goods/wssd_content.jsp?bookid=<!--goodid-->
淘宝技术这十年 /module/goods/wssd_content.jsp?bookid=35948
高性能MySQL(第3版) /module/goods/wssd_content.jsp?bookid=35789
在你身边,为你设计:腾讯的用户.. /module/goods/wssd_content.jsp?bookid=34821
网络营销实战密码——策略、技巧.. /module/goods/wssd_content.jsp?bookid=35862
上帝之眼——旅行者的摄影书(全.. /module/goods/wssd_content.jsp?bookid=34653
我的环保行动书(1-4册)(全.. /module/goods/wssd_content.jsp?bookid=22452
向诸葛亮借智慧(含DVD光盘1.. /module/goods/wssd_content.jsp?bookid=21651
平衡计分卡导入与实施(修订版) /module/goods/wssd_content.jsp?bookid=27331

讲道理,我们应该是整理好了。但是运行中,仍然有一行特殊的 “/module/goods/wssd_content.jsp?bookid=<!--goodid-->”,于是我们在if条件里继续加上以下代码即可:

from bs4 import BeautifulSoup
with open('bydict_网上书店2.html','r',encoding='gbk') as f:
    bs=BeautifulSoup(f.read(),'lxml')
    a_lst=bs.find_all('a')
    for a in a_lst:
        if a.text!='' and 'wssd_content.jsp?bookid' in a['href'] and '<!--goodid-->' not in a['href']:
            print(a.text.strip(),a['href'])

运行结果如下所示:

摄影的骨头:高品质数码摄影流程.. ./wssd_content.jsp?bookid=36518
通往独立之路:摄影师生存手册(.. ./wssd_content.jsp?bookid=36519
淘宝技术这十年 /module/goods/wssd_content.jsp?bookid=35948
高性能MySQL(第3版) /module/goods/wssd_content.jsp?bookid=35789
在你身边,为你设计:腾讯的用户.. /module/goods/wssd_content.jsp?bookid=34821
网络营销实战密码——策略、技巧.. /module/goods/wssd_content.jsp?bookid=35862
上帝之眼——旅行者的摄影书(全.. /module/goods/wssd_content.jsp?bookid=34653
我的环保行动书(1-4册)(全.. /module/goods/wssd_content.jsp?bookid=22452
向诸葛亮借智慧(含DVD光盘1.. /module/goods/wssd_content.jsp?bookid=21651
平衡计分卡导入与实施(修订版) /module/goods/wssd_content.jsp?bookid=27331

当然,我们还可以用其他的方法达到相同的目标。接下来,我们就看一下其他方法:

from bs4 import BeautifulSoup
with open('bydict_网上书店2.html','r',encoding='gbk') as f:
    bs=BeautifulSoup(f.read(),'lxml')
    div_lst=bs.find_all('div',attrs={'style':'width:496px; float:left; display:inline;margin:10px 0px 0px 16px;'})
    for div in div_lst:
        a_lst=div.find_all('a')
        for a in a_lst:
            if '/module/goods/' not in a['href']:
                print(a.text.strip(),a['href'])

结果如下所示:

摄影的骨头:高品质数码摄影流程.. ./wssd_content.jsp?bookid=36518
通往独立之路:摄影师生存手册(.. ./wssd_content.jsp?bookid=36519

为啥只有两个?因为我们选取的页面,并不是所有商品的页面,而是商品页面的一个首页。页面里我们要找的商品div元素的style有太多不同的样式,我们只选取了一种讲解。

这一节的讲解,主要是让我们掌握基础的网页处理,由于技术的更新,我更推荐使用lxml来做网页处理。

lxml方法就先留给大家去自学吧,如果以后我用到了,我也会在博客中分享的。

猜你喜欢

转载自blog.csdn.net/dylan_me/article/details/80931140
今日推荐