对于需要登陆的网站用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| ||)")
EndCharToNoneRex = re.compile("<.*?>")
BgnPartRex = re.compile("")
CharToNewLineRex = re.compile("
||||")
CharToNextTabRex = re.compile("")
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(' .*?(.*?) .*?(.*?) .*?(.*?) .*?.*? (.*?) .*? (.*?) .*?(.*?) .*?(.*?) .*? ',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/
祝好运!