python爬虫Pragmatic系列III

python爬虫Pragmatic系列III

说明:

在上一篇博客中,我们已经学会了从赶集网上的一家公司中提取出有关的信息,并存储到Excel中。

本次目标:

在本节中,我们将批量下载赶集首页上所有的公司界面(注意不是赶集网上所有的公司页面,我们可以把这个留给之后的任务),并批量的处理所有公司的有关信息,并保存到Excel中。

注意:

在上一篇博客中,我们使用的只是匹配赶集网上其中一家公司界面的中信息,而且不幸的是,很多的其他的公司的联系店主模块中的信息数量并不是固定的,即有的是10个li,而有的是9个li或者12个li,而且并不是所有公司都提供了QQ联系方式或者公司名称。所以,我对代码稍微做了处理,使其能够适应大部分的网页。

批量下载网页:

如下图:

我们将提取出该网页所包含的公司链接,并批量下载下来。这次,我们使用了一个下载类,利用下载类来封装我们所要的方法。我们先给定赶集网的首页链接,下载首页,接着我们分析出首页包含的公司链接并保存起来,最后我们将这些链接都下载到pagestroage文件夹中。

代码:

#-*-coding:utf-8-*-
import re
import os
from urllib import urlretrieve
from bs4 import BeautifulSoup

class Download(object):
    '该类将包含下载给定的url和将其保存    为相应的文件的方法'
    def __init__(self):
        self.index = 0
        #初始化

    def getPages(self,url,isMain=False):
        '根据给定的url进行下载,如果是赶集网主界面,则另行处理'
        for u in url:
            try:
                revtal = urlretrieve(u)[0]
            except IOError:
                revtal = None
            if revtal <> None and isMain == True:
                #是赶集网主界面
                self.savePages(revtal, isMain=True)
            elif revtal <> None and isMain <> True:
                self.savePages(revtal)
            else:
                print('Open url error')

    def savePages(self,webpage,isMain=False):
        '将给定的网页保存起来'
        f = open(webpage)
        lines = f.readlines()
        f.close()

        if isMain == False:
            #不是主界面则按序存储为filei.txt,i为序号
            fobj = open("pagestroage\\file%s.txt"%str(self.index), 'w')
            self.index += 1
            fobj.writelines(lines)
        else:
            #是赶集网主界面,则存储为mian.txt
            fobj = open("pagestroage\main.txt",'w')
            fobj.writelines(lines)

        fobj.close()

    def getAllComUrls(self):
        '我们对赶集网的主界面进行分析,提取出所有公司的链接,保存起来'
        if os.path.exists('pagestroage\main.txt'): #判断文件是否存在
            fobj = open('pagestroage\main.txt','r')
            lines = fobj.readlines()
            fobj.close()

            soup = BeautifulSoup(''.join(lines))
            body = soup.body
            #wrapper = soup.find(id="wrapper")
            leftBox = soup.find(attrs={'class':'leftBox'})
            list_ = leftBox.find(attrs={'class':'list'})
            ul = list_.find('ul')
            li = ul.find_all('li')
            href_regex = r'href="(.*?)"'
            urls = []

            for l in li:
                urls.append('http://bj.ganji.com' + re.search(href_regex,str(l)).group(1))
            #print urls

            return urls
        else:
            print('The file is missing')
            return None

if __name__ == '__main__':
    #初试设定url为赶集网首页
    url=['http://bj.ganji.com/danbaobaoxian/o1/']
    #实例化下载类
    download = Download()
    #先下载赶集网首页
    download.getPages(url,True)
    #对下载的赶集网首页信息进行分析,提取出所有公司的url
    urls = download.getAllComUrls()
    #对上面提取的url进行下载
    download.getPages(urls)

运行结果:

我们得到了十几个包含公司网页的文本文件。如下图:

分析网页:

由上面的操作,我们已经得到了赶集网上所有公司的html文本。接着我们使用Analysiser类来处理我们得到的数据。注意,Analysiser类中的方法基本上都在前面的博客中介绍了,这里只是用类封装了,并使其能够批量处理。

代码:

#-*-coding:utf-8-*-
import re
from bs4 import BeautifulSoup
import xlwt
import os
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

class Analysiser(object):
    '该类将分析下载的公司信息存储到Excel表格中'
    def __init__(self):
        '初始化一个Excel'
        self.wb = xlwt.Workbook()
        self.ws = self.wb.add_sheet('CompanyInfoSheet')
        self.initExcel()

    def initExcel(self):
        '我们初试化一个表格,并给表格一个头部,所以我们给头部不一样的字体'
        #初始化样式
        style = xlwt.XFStyle()
        #为样式创建字体
        font = xlwt.Font()
        font.name = 'Times New Roman'
        font.bold = True
        #为样式设置字体
        style.font = font 

        # 使用样式
        #写入公司名称
        self.ws.write(0,0,u'公司名称', style)
        #写入服务特色
        self.ws.write(0,1,u'服务特色', style)
        #写入服务范围
        self.ws.write(0,2,u'服务范围', style)
        #写入联系人
        self.ws.write(0,3,u'联系人', style)
        #写入商家地址
        self.ws.write(0,4,u'商家地址', style)
        #写入聊天QQ
        self.ws.write(0,5,u'QQ', style)
        #写入联系电话
        self.ws.write(0,6,u'联系电话', style)
        #写入网址
        self.ws.write(0,7,u'公司网址', style)
        self.wb.save('xinrui.xls')

    def analysAllFiles(self):
        '''
        批量分析网页源码,并提取出公司相关信息
        '''
        #得到pagestroage(我们存放下载的公司网页的文件夹)下所有的文件
        filenames = os.listdir('pagestroage')
        #得到所有存储的公司数目(去除一个包含赶集网首页的main.txt)
        counts = len(filenames) - 1
        #循环处理
        for i in range(counts):
            #打开文件,读文件到lines中,关闭文件对象
            f = open("pagestroage\\file%s.txt"%i, 'r')
            lines = f.readlines()
            f.close()

            #这两个网页的联系店主模块与其他的不一样,如果也要匹配只能重新写代码匹配,遂放弃
            if i == 12 or i == 7:
                continue

            #建立一个BeautifulSoup解析树,并利用这课解析树依次按照
            #soup-->body-->(id为wrapper的div层)-->(class属性为clearfix的div层)
            #-->(id为dzcontactus的div层)-->(class属性为con的div层)-->ul-->(ul下的每个li)
            soup = BeautifulSoup(''.join(lines))
            body = soup.body #body2 = soup.find('body')
            wrapper = soup.find(id="wrapper")
            clearfix = wrapper.find_all(attrs={'class':'d-left-box'})[0]
            dzcontactus = clearfix.find(id="dzcontactus")
            con = dzcontactus.find(attrs={'class':'con'})
            ul = con.find('ul')
            li = ul.find_all('li')

            #记录一家公司的所有信息,用字典存储,可以依靠键值对存取,也可以换成列表存储
            record = {} 

            #公司名称
            companyName = li[1].find('h1').contents[0]
            record['companyName'] = companyName

            #服务特色
            serviceFeature = li[2].find('p').contents[0]
            record['serviceFeature'] = serviceFeature

            #服务提供
            serviceProvider = []
            serviceProviderResultSet = li[3].find_all('a')
            for service in serviceProviderResultSet:
                serviceProvider.append(service.contents[0])

            record['serviceProvider'] = serviceProvider

            #服务范围
            serviceScope = []
            serviceScopeResultSet = li[4].find_all('a')
            for scope in serviceScopeResultSet:
                serviceScope.append(scope.contents[0])

            record['serviceScope'] = serviceScope

            #联系人
            contacts = li[5].find('p').contents[0]
            contacts = str(contacts).strip().encode("utf-8")
            record['contacts'] = contacts

            #商家地址
            addressResultSet = li[6].find('p')
            re_h=re.compile('</?\w+[^>]*>')#HTML标签
            address = re_h.sub('', str(addressResultSet))
            record['address'] = address.encode("utf-8")

            restli = ''
            for l in range(8,len(li) - 1):
                restli += str(li[l])

            #商家QQ
            qqNumResultSet = restli
            qq_regex = '(\d{5,10})'
            qqNum = re.search(qq_regex,qqNumResultSet).group()
            qqNum = qqNum
            record['qqNum'] = qqNum

            #联系电话
            phone_regex= '1[3|5|7|8|][0-9]{9}'
            phoneNum = re.search(phone_regex,restli).group()
            record['phoneNum'] = phoneNum

            #公司网址
            companySite = li[len(li) - 1].find('a').contents[0]
            record['companySite'] = companySite

            self.writeToExcel(record,i + 1)

    def writeToExcel(self,record,index):
        '该函数将给定的record字典中所有值存储到Excel相应的index行中'
        #写入公司名称
        companyName = record['companyName']
        self.ws.write(index,0,companyName)

        #写入服务特色
        serviceFeature = record['serviceFeature']
        self.ws.write(index,1,serviceFeature)

        #写入服务范围
        serviceScope = ','.join(record['serviceScope'])
        self.ws.write(index,2,serviceScope)

        #写入联系人
        contacts = record['contacts']
        self.ws.write(index,3,contacts.decode("utf-8"))

        #写入商家地址
        address = record['address']
        self.ws.write(index,4,address.decode("utf-8"))

        #写入聊天QQ
        qqNum = record['qqNum']
        self.ws.write(index,5,qqNum)

        #写入联系电话
        phoneNum = record['phoneNum']
        phoneNum = str(phoneNum).encode("utf-8")
        self.ws.write(index,6,phoneNum.decode("utf-8"))

        #写入网址
        companySite = record['companySite']
        self.ws.write(index,7,companySite)
        self.wb.save('xinrui.xls')

if __name__ == '__main__':
    ana = Analysiser()
    ana.analysAllFiles()

运行结果:

我们将得到包含赶集网首页上包含的所有公司的相关信息的Excel,如下图:

后感:

看到这个Excel是不觉得很cool,终于能做点实际的事情了。

不过,我们还可以做的更好,更智能。

未完待续。

时间: 2025-01-01 11:32:05

python爬虫Pragmatic系列III的相关文章

Python爬虫Csdn系列III

Python爬虫Csdn系列III By 白熊花田(http://blog.csdn.net/whiterbear) 转载需注明出处,谢谢. 说明: 在上一篇博客中,我们已经能够获取一个用户所有文章的链接了,那么这一节自然就是要将这些博客下载下来咯. 分析: 有了链接下载文章自然是不难.但是,获取的数据该怎么处理?每一篇文章都带有格式换行这些信息,自然,我们存储它们也是要存储其对应的html格式的数据的(注意,我们编辑的带有格式的博客或者其他文本都是以html代码格式存储的).如何存?使用数据库

python爬虫Pragmatic系列IV

python爬虫Pragmatic系列IV 说明: 在上一篇博客中,我们已经做到了从赶集网上单个首页中抓取所有的链接,并下载下来,分析后存入Excel中. 本次目标: 在本节中,我们将使用python多线程技术从赶集网上抓取链接并分析,注意,我们这次能够抓获的链接数目可以远远大于上一篇博客中抓获的. 分析: 用爬虫统计信息那自然数据越多越好,为了获取更多的数据,我们先研究下如何打开上千个赶集网上公司链接. 打开首页(http://bj.ganji.com/danbaobaoxian/o1/),在

Python爬虫学习系列教程

Python爬虫学习系列教程 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己实际写的一些小爬虫,在这里跟大家一同分享,希望对Python爬虫感兴趣的童鞋有帮助,如果有机会期待与大家的交流. Python版本:2.7 一.爬虫入门 1. Python爬虫入门一之综述 2. Python爬虫入门二之爬虫基础了解 3. Python爬虫入门三之Urllib库的基本使用 4. Python爬虫入门四之Urllib库

Python爬虫Csdn系列I

Python爬虫Csdn系列I By 白熊花田(http://blog.csdn.net/whiterbear) 说明: 我会在这个系列介绍如何利用python写一个csdn爬虫,并将给定的Csdn用户的博客的所有文章保存起来.嗯,实用性貌似不是很大,写着玩,这个系列后,会有更好玩的更高级的爬虫出现. 原因: 本来想学cookie的,后来发现爬取csdn的文章伪装成浏览器去访问就行了. 本次目标: 爬取csdn某用户的文章列表.这里以我的blog为例,仅仅打开第一列文章列表,不做任何分析,只是验

Python爬虫Csdn系列II

Python爬虫Csdn系列II By 白熊花田(http://blog.csdn.net/whiterbear) 转载需注明出处,谢谢. 说明: 在上一篇文章中,我们已经知道了只要将程序伪装成浏览器就能访问csdn网页.在这篇文章中,我们将设法获取某个csdn用户的所有文章的链接. 分析: 打开一个某一个的csdn用户的的专栏,可以选择目录视图(如:http://blog.csdn.net/whiterbear?viewmode=contents)和摘要视图(比如:http://blog.cs

《Python爬虫学习系列教程》学习笔记

转自:http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己实际写的一些小爬虫,在这里跟大家一同分享,希望对Python爬虫感兴趣的童鞋有帮助,如果有机会期待与大家的交流. 一.Python入门 1. Python爬虫入门一之综述 2. Python爬虫入门二之爬虫基础了解 3. Python爬虫入门三之Urllib库的基本使用 4. Python爬虫

Python爬虫开发系列之一》开发IDE安装

中国有句古话说:工欲善其事,必先利其器! 在我最开始学 Python 的时候,因为没有去探索好用的工具,吃了很多苦头.磕磕绊绊走过来之后才知道,好的工具给效率带来的提升不是从 1 到 1.1 倍速,而是从 1 到 10 倍速. 所以说编写和运行程序之前我们必须要先把开发环境配置好,只有配置好了环境并且有了更方便的开发工具我们才能更加高效地用程序实现相应的功能达到事半工倍的效果,然而很多情况下我们可能在最开始就卡在环境配置上,如果这个过程花费了太多时间,想必学习的兴趣就下降了大半,所以本章专门开发

Python爬虫开发系列之三》Requests请求库的使用

Requests是一个实用.简单.强大的Python HTTP客户端库,编写爬虫和测试服务器响应数据时经常会用到.Requests 能够完全满足如今网络的需求.接下来我们从最基本的get post 请求开始 到高级特性一步一个脚印去学习.学习是个渐进的过程,只有脚踏实地不断的去练习才能掌握这些重要的知识点. 一.发送请求 get /post 按照规例首先要导入Requests模块>>> import requests r=requests.get('https://www.baidu.c

python爬虫beautifulsoup4系列1

前言 以博客园为例,爬取我的博客上首页的发布时间.标题.摘要,本篇先小试牛刀,先了解下它的强大之处,后面讲beautifulsoup4的详细功能. 一.安装 1.打开cmd用pip在线安装beautifulsoup4 >pip install beautifulsoup4 二.解析器 1.我们主要用第一个html.parser,这个是python的标准库,可以直接用.其它几个需要安装对应解析器, 下表列出了主要的解析器,以及它们的优缺点: 三.打印首页博客的时间 1.这里直接定位不好定位到,可以