实战BeautifulSoup

bs4是Python中一个非常常用的解析网页获取目标内容的模块,在爬虫中经常被引用。虽然知乎上已有大神比较过不同选择器的速度,实际检测的结论应该是xpath最快,(当然正则表达式更快),然而BeautifulSoup的lxml也不慢。

 

实际上,大家在爬取过程中都有直观的感觉,大多数时间耗费在发送请求及返回文件(以及刻意休眠等待),实际处理html或json文件的时间相比之下几乎可以忽略不计。鉴于博主最先上手BeautifulSoup并且所需数据量级没有百万那么夸张,于是一直用BeautifulSoup。一个教程几乎搞定所有问题。

 

实际情况不比教程简单,博主写了几个script后,想分享一些BeautifulSoup具体应用的案例(万一有小伙伴觉得有用呢,笑),全部都是B2B平台公开的企业联系方式数据。

 

案例1-黄页88

开始URL链接:http://b2b.huangye88.com/shenzhen/fuwu/

目标:爬取所有页中公司名称联系方式

观察:每页显示公司数量一定;总公司数量在页面中可以找到;翻页后发现URL后加’pn2/’

思路:由开始的URL获取页面,从页面中获取总公司数量,计算可得总页数,通过循环获得所有页面URL,分别访问每个URL获取该页展示的信息

 

右键查看源代码,我们想要的公司数量在以下代码片段中:

<div class="tittit2"><h3 style="width:40%;">深圳商务服务公司</h3><spanstyle="float:right;padding-right:10px">深圳商务服务名录共收录<em>18908</em>个深圳商务服务公司资料</span></div>

BeautifulSoup有搜索tag的功能,了解html的同学都知道<em>标签是加粗的意思,而我们想要的公司数量正好在这个tag里,如果整个页面只有一个<em>标签,那搜索就轻而易举了。Ctrl+F搜索关键词<em>发现真的只有一个结果。于是公司数量就可以这样提取:

headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.109 Safari/537.36'} #伪装成浏览器
page1Url = r” http://b2b.huangye88.com/shenzhen/fuwu/”
page1 = requests.get(page1Url, headers=headers)
soup = BeautifulSoup(page1.text, 'lxml')  
companyNo = int(soup.find('em').string)

值得注意的是,为了对抗反爬虫机制,在请求中加入伪装成浏览器的请求头。


一般来说,公司列表会装在一个大div中,并且这个div一般会有class这个属性。右键检查(Chrome)找到盛装公司列表的tag,发现是一个<form>。将页面做成soup之后找到这个<form>,并将其中所有<dl>放进list,每个<dl>包含一家公司的信息,通过循环遍历获取。如下图:


companies = soup.find('form', id='jubao')
if companies == None:
    print "Error Page"
    return
companies = companies.find_all('dl')


打开一个<dl>标签之后发现,公司名字放在唯一的<h4>标签中,而电话号码在一个itemprop=”tel”的span中。如下图:


h4 = company.find('h4')
name = h4.a.string
phone =company.find('span',attrs={"itemprop":"tel"}).a.string

 

由于有些公司提供的联系方式是电话,而老板需要将电话与手机分开,所以需要以下代码:

mobile = re.findall("(1\\d{10})",phone)             #正则表达式查找并提取所有手机号,一般只能找到1个或者没有
if len(mobile) != 0:
    mobile = mobile[0]
    telephone = 'NA'
else:
    mobile = 'NA'
    telephone = phone

最后将公司信息存入字典:

comInfo = {}
comInfo['name'] = name
comInfo['mobile'] = mobile
comInfo['telephone'] = telephone

或者直接写入csv:

with open('hy88.csv','wb') as csvfile:              #需要事先import csv
    writer =csv.writer(csvfile, dialect='excel')
    writer.writerow([name, mobile, telephone])

 

案例2-网易

开始链接:http://114.163.com/search/2/1983-11-31-2007/?q=&s=10&p=0

目标:爬取北上广深四个城市所有金融/银行/保险业的公司信息

观察:每页显示10间公司,公司总数量在首页显示,翻页后URL最后p=1

思路:类似案例1

 

右键检查,Ctrl+Shift+C(Chrome快捷键)鼠标移动至希望检查的元素上,对应代码段落就会被高亮,如下图。


发现每条公司信息都被放在class=‘info’的div里面,于是我们通过BeautifulSoup查找到所有并循环遍历。

companies = soup.find_all('div', class_='info')

我们需要的信息有地址,联系电话/手机,电邮。地址是在class=”contact”的<ul>下第一个<li>标签内。但是当该公司没有地址可以显示时,联系电话/手机变成第一个<li>的内容。因此我们通过搜索class=”icon-addr”的<span>定位地址。同理,通过class=”icon-tel”的<span>定位联系方式,通过class=”icon-email”的<span>定位电邮所在。


 

phone = company.find(class_='icon-tel')                  #这里的phone实际是一个小图标(icon)
if phone == None:                                        #公司没有联系方式展示
    mobile = 'NA'
    telephone = 'NA'
else:    
    phone = phone.previous_element.string                #获取联系方式,返回的phone即是上图中“101-85109619”
    mobile = re.findall("(1[3458]\\d{9})",phone)         #查找是否有手机号
    if len(mobile) != 0:
        mobile = mobile[0]
        telephone = 'NA'
    else:
        mobile = 'NA'
        telephone = phone

email = company.find(class_='icon-email')                #这里的email实际是一个小图标
if email != None:                                        #公司有电邮展示,即查找到email图标
    email = email.previous_sibling.string
else:
    email = 'NA'

address = company.find(class_='icon-addr')
if address == None:
    continue
address = address.previous_element.string

 

详细功能列举: <br> 1.实时显示哪在用户在线,会员关闭网页自动退出功能,可显示用户采用什么浏览器和操作系统,彻底杜绝一帐号多用户使用 <br> 2.增加了网站投票功能 <br> 3.采用双网站联盟,用户可以选择介绍客户赚佣金或介绍客户赚看片资源。 <br> 4.扣点功能,每一部影片站长可以按照他的价值设定需要扣取的点数 <br> 5.后台增加网吧IP功能,在该网吧上网的用户可以免注册免付费看电影 <br> 6.使用充值卡的用户无需要注册激活充值卡后就可以使用 <br> 7.用户自助赚点功能,用户注册后可以获取一段代码,可以对电影网站进行宣传.每带来一个用户访问宣传用户就可以获得(1点[扣点用户]/0.2天[包月用户或游客]) <br> 8.来路分析,可以看到网民是从哪个网站来的,或看到该网民是由哪个用户宣传带来的. <br> 9.IP限制,被限制的ip将无法访问 <br> 10.黄金通道,只有黄金会员以上级别才可以进入。 <br> 11.后台管理员密码采用md5加密,极大地保护了后台的安全 <br> 12.会员密码采用md5加密,极大地保护了会员的安全 <br> 13.数据库采用在线管理 <br> 14.改变了局部一些使用不方便的功能 <br> 15.在线支付、手机支付、声讯支付功能,会员付费后自动开通到期自动封帐号,程序会自动跟据会员付多少钱而给会员定相应的级别和相应的观看时间,会员到期程序自动封锁帐号。 <br> 16.采用ACCESS2002数据库和ACCESS2000数据库两种任君选择,我们制作的数据库非常安全是无法被非法下载的请君放心。 <br> 17.修正了一些漏洞(彻底跟黄金眼说拜拜) <br> 18.多级管理员操作,演员搜索 <br> 19.下载地址和在线地址实现分离 <br> 20.观看电影记录,会员可以查看自己过去观看过多少部电影(电影名称、观看电影时间),会员报告影片错误功能。 <br> 21.管理员可以在后台查看各个会员的观看记录,可以根据会员看不同电影的时间、会员的ip地址,判断会员是否有盗链。 <br> 22.管理员在后台可随时改变会员等级,实行会员分类管理。 <br> 23.电影可以设置为免费电影、普通电影、黄金电影。 <br> 24.隐藏影片地址功能,彻底防盗链。 25.内置1st-pay在线支付功能,用户只需在后台设置好1st-pay的用户名及返回URL即可使用,无需修改程序。支付成功返回的URL是user/payok.asp 后台地址:admin/login.asp 管理账号:163dy/163dy
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值