Python网络爬虫——模拟登陆爬取网站数据并加载到excl表格里

对于需要登陆的网站用Python写爬虫的时候需要模拟登陆上去,才能得到想要的界面。

偶然的一个机会,以前的辅导员找到我,想写一个爬取网络表格到本地excl表格并能支持获取分页数据的小程序,碰巧以前写过爬虫,这样一来又深入的理解了一下。前段时间忙着面试一直没抽出时间,今天花了一天的功夫算是搞出来了。写一个博客,以后查找时方便,也希望能给同样再写爬虫的童鞋一点帮助!

模拟登陆首先要分析一下浏览器给服务器发送的包,就需要有一个抓包程序,推荐大家使用:Fiddler4。下载安装之后,在开启Fiddler时访问网页就能捕获包文,十分方便,同时它也能捕获Python的包文,对调试时很有帮助。

整个流程就是模拟浏览器给服务器发包,然后将将需要的文件从浏览器获取,通过正则表达式将所需要的内容挖出来,然后就是保存到excl表格里了。对于正则表达是部分是Python的基础,我就不重复造轮子了,推荐百度一下。另外值得一提的就是,将数据保存到excl里和记事本里不一样,需要特殊处理一下。请参考以下代码:

#encoding:utf8
import xlrd
import xlwt

class OperExcel():
  #读取Excel表
  def rExcel(self,inEfile,outfile):
    rfile = xlrd.open_workbook(inEfile)
    #创建索引顺序获取一个工作表
    table = rfile.sheet_by_index(0)
    #其他方式
    #table = rfile.sheets()[0]
    #table = rfile.sheet_by_name(u'Sheet1')

    #获取整行,整列的值
    table.row_values(0)
    table.col_values(0)

    #获取行数和列数
    nrows = table.nrows - 1
    ncols = table.ncols

    #循环获取列表的数据
    #for i in range(nrows):
    #  print table.row_values(i)
    wfile = open(outfile,'w')
    #获取第一列中的所有值
    for i in range(nrows):
      #table.cell(i,0).value获取某一单元格的值
      wfile.write(table.cell(i,0).value.encode('utf8') + '\n')
    wfile.close()

#将数据写入Excel表
  def wExcel(self,infile,outEfile):
    rfile = open(infile,'r')
    buf = rfile.read().split('\n')
    rfile.close()

    w = xlwt.Workbook()
    sheet = w.add_sheet('sheet1')
    for i in range(len(buf)):
      print buf[i]
      sheet.write(i,0,buf[i].decode('utf8'))
    w.save(outEfile)

if __name__ == '__main__':
  t = OperExcel()
  t.rExcel('test.xls','test')
  t.wExcel('test','1.xls')

#encoding:utf8
import xlrd
import xlwt

class OperExcel():
  #读取Excel表
  def rExcel(self,inEfile,outfile):
    rfile = xlrd.open_workbook(inEfile)
    #创建索引顺序获取一个工作表
    table = rfile.sheet_by_index(0)
    #其他方式
    #table = rfile.sheets()[0]
    #table = rfile.sheet_by_name(u'Sheet1')

    #获取整行,整列的值
    table.row_values(0)
    table.col_values(0)

    #获取行数和列数
    nrows = table.nrows - 1
    ncols = table.ncols

    #循环获取列表的数据
    #for i in range(nrows):
    #  print table.row_values(i)
    wfile = open(outfile,'w')
    #获取第一列中的所有值
    for i in range(nrows):
      #table.cell(i,0).value获取某一单元格的值
      wfile.write(table.cell(i,0).value.encode('utf8') + '\n')
    wfile.close()

#将数据写入Excel表
  def wExcel(self,outEfile):
    # rfile = open(infile,'r')
    # buf = rfile.read().split('\n')
    # rfile.close()
    buf = [ ['HK2815','其它','广州','2015第117届中国进出口商品交易会(2015年春季广交会)纸书版会刊123期全套[预订][包邮];','2015年04月15日 - 05月05日','广州','琶洲会展中心','10000'],
            ['HK2809','美容美发','上海','2014第21届上海国际美容美发化妆品博览会;','2014年11月03日-11月05日','上海','光大会展中心','128']
          ]
    w = xlwt.Workbook()
    sheet = w.add_sheet('sheet1')
    for i in range(len(buf)):
      for j in  range(len(buf[i])):
      # print buf[i]
        sheet.write(i,j,buf[i][j].decode('utf8'))
    w.save(outEfile)

if __name__ == '__main__':
  t = OperExcel()
  #t.rExcel('test.xls','test')
  t.wExcel('test.xls')

然后就是代码的主程序了,细节问题请看主代码:

#-*- coding: UTF-8 -*-
import urllib
import urllib2
import requests
import re
import codecs
import xlwt

#作用就是将html文件里的一些标签去掉,只保留文字部分
class HTML_Tool:
    BgnCharToNoneRex = re.compile("(\t|\n| |<a.*?>|<img.*?>)")
    EndCharToNoneRex = re.compile("<.*?>")
    BgnPartRex = re.compile("<p.*?>")
    CharToNewLineRex = re.compile("<br/>|</p>|<tr>|<div>|</div>")
    CharToNextTabRex = re.compile("<td>")

    def Replace_Char(self,x):
        x=self.BgnCharToNoneRex.sub("",x)
        x=self.BgnPartRex.sub("\n   ",x)
        x=self.CharToNewLineRex.sub("\n",x)
        x=self.CharToNextTabRex.sub("\t",x)
        x=self.EndCharToNoneRex.sub("",x)
        return x

#爬虫类
class Spider:
    def __init__(self,parll,headerss,num):
        self.num = num+1
        self.par1 = parll
        self.headers = headerss
        self.s = requests.session()
        self.login = ""
        self.datas = []
        self.myTool = HTML_Tool()
        print u'会刊网爬虫程序已启动,正尝试登陆...'

    def Solve(self):
        self.Login()
        self.get_data()
        # self.save_data(3)
        self.wExcel('huikan.xls')

    def wExcel(self, outEfile):
        w = xlwt.Workbook()
        sheet = w.add_sheet('sheet1')
        for i in range(len(self.datas)):
            for j in range(len(self.datas[i])):
                # print buf[i]
                sheet.write(i, j, self.datas[i][j].decode('utf8'))
        w.save(outEfile)
        print u'爬虫报告:会刊目录已保存至当前文件夹下huikan.xls文件'
        print u'加载完成,按任意键退出爬虫程序'
        raw_input()
    # def save_data(self,endpage):
    #     f = codecs.open('huikan.xls','w+', "utf-8")
    #     for i in self.datas:
    #         str = u""
    #         for j in i:
    #             str=str+j.decode('utf-8')
    #         f.writelines(str+u'\n')
    #     f.close()
    #     print u'爬虫报告:会刊目录已保存至当前文件夹下huikan.xls文件'
    #     print u'加载完成,按任意键退出爬虫程序'
    #     #raw_input()

    def Login(self):
        loginURL = "http://www.huikan.net/Login.asp?Action=Login"
        self.login = self.s.post(loginURL,data = self.par1,headers = self.headers)
        print u'爬虫报告:模拟浏览器登陆成功,正在爬取资料...'

    def get_data(self):
        for i in range(1,self.num):
            print u'爬虫报告:爬虫%d号正在加载中...' %i
            afterURL = "http://www.huikan.net/allehuikan.asp?page="
            response = self.s.get(afterURL+str(i), cookies = self.login.cookies,headers = headers)
            mypage = response.content
            self.deal_data(mypage.decode('utf-8'))
            #print mypage

    def deal_data(self,mypage):
        myItems = re.findall('<tr>.*?<td height="30" class="tdcs" align="center" width="70">(.*?)</td>.*?<td height="30" class="tdcs" align="center" width="90">(.*?)</td>.*?<td height="9" align="center" class="tdcs" width="50">(.*?)</td>.*?<td height="9" class="tdcs">.*? (.*?)</a></td>.*?<td height="9" class="tdcs" width="170" align="center"> (.*?)</td>.*?<td height="9" align="center" class="tdcs" width="100">(.*?)</td>.*?<td height="9" class="tdcs" width="40" align="center">(.*?)</td>.*?</tr>',mypage,re.S)
        #print myItems
        for item in myItems:
            items = []
            #print item[0]+' '+item[1]+' '+item[2]+' '+item[3]+' '+item[4]+' '+item[5]+' '+item[6]
            items.append(item[0].replace("\n",""))
            items.append(item[1].replace("\n",""))
            items.append(item[2].replace("\n", ""))
            items.append(item[3].replace("\n", ""))
            items.append(item[4].replace("\n", ""))
            items.append(item[5].replace("\n", ""))
            items.append(item[6].replace("\n", ""))
            #print items
            mid = []
            for i in items:
                mid.append(self.myTool.Replace_Char(i.replace("\n","").encode('utf-8')))
            #print mid
            self.datas.append(mid)
        #print self.datas

#----------- 程序的入口处 -----------
print u"""
----------------------------------------------------------
   程序:网络爬虫
   版本:V01
   作者:lvshubao
   日期:2016-04-11
   语言:Python 2.7
   功能:将会刊网中会刊目录保存到当前目录下的huikan.xls表格
   操作:按任意键开始执行程序,加载时间可能会很长,请耐心等待
----------------------------------------------------------
"""
raw_input()
headers = {'Cache-Control': 'max-age=0','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','Origin': ' http://www.huikan.net','Upgrade-Insecure-Requests': '1','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36','Accept-Language': 'zh-CN,zh;q=0.8','Cookie': 'pgv_pvi=7133927424; news=2014%u4E2D%u56FD%u56FD%u9645%u4FE1%u606F%u901A%u4FE1%u5C55%u89C8%u4F1A%A0%u7B2C1%u9875%204%u67083%u65E5%2012%3A52^http%3A//www.huikan.net/viphuikan.asp%3Fscck%3D1%26id%3D2588%26page%3D1$2014%u4E2D%u56FD%u56FD%u9645%u4FE1%u606F%u901A%u4FE1%u5C55%u89C8%u4F1A%A0%u7B2C1%u9875 4月3日 12:53^http%3A//www.huikan.net/viphuikan.asp%3Fscck%3D1%26id%3D2588%26page%3D1$|; ASPSESSIONIDSAQTDTSB=FHCEDBJAHJGPCOKONMNLEOGH; ASPSESSIONIDQATQARQC=DGKDMPABKDHMOHEAKJCLLJFB; pgv_si=s1220992000; PPst%5FLevel=3; PPst%5FUserName=handwudi; ehk%5Fname=handwudi; PPst%5FLastIP=222%2E171%2E12%2E123; PPst%5FLastTime=2016%2F4%2F10+18%3A27%3A38; visits=18; AJSTAT_ok_pages=2; AJSTAT_ok_times=4'}
data = {"Username":"123456","Passwrod":"123456","B1":"登陆"}
print u'请输入爬虫需要爬取的页数:'
num = raw_input()
myspider = Spider(data,headers,int(num))
myspider.Solve()

tip:有些Python模块可能找不到,别忘了自己用pip install 去下载,另外推荐一个很全的网址:http://www.lfd.uci.edu/~gohlke/pythonlibs/

祝好运!


  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值