• Python3.6下使用会话session保持登陆状态


      本次工具主要利用python easygui模块的inputbox让用户首次输入登陆信息,作为网站requests-post请求的data字段,观察XHR(异步加载)的数据包,构造post请求,利用requests库的session功能保持登陆状态,进而请求其他子页下的所需信息,最终爬取到本地excel文件中。

    我们手工登陆后,网站会进行跳转,通过浏览器F12查看network页签,logindo页面可以看到登陆后服务器在response headers栏 有set-cookie:

    但是网站登陆redirect后的页面并没有看到:response.cookies;

    如果利用response.cookies将得到一个空的RequestsCookieJar对象,无法为后续的信息爬取提供cookies字段放入headers栏,此时可以考虑用response.session保持首次登陆状态,后续服务器端在session有效期内不会再要求页面传入登陆信息,主要代码如下,:

    import requests,json,easygui,os,sys,math,time
    from openpyxl import load_workbook
    msg = "请输入OA用户名和密码"
    title = "用户登录入口"
    user_info = []
    user_info = easygui.multpasswordbox(msg,title,("用户名","密码"))
    start = time.time()
    pwd = os.getcwd()
    
    wb = load_workbook(filename=pwd+u"\info_list.xlsx")
    sheet=wb[u"参数"]
    
    base_url='http://******.com/srm/supplier/Criteria.do'
    
    loginData={'redirect':'','username':user_info[0],'password':user_info[1]}
    #下面的data-search字典中,condition键其实就是Oracle数据库的select条件在网页中的集成形式,通过设置exp表达式以及value等,可以灵活的查询,突破页面集成的查询默认条件限制。 data_search
    ={ 'page':1,#控制请求的页面数 'rows':100,#控制每页显示的行数 'condition':'[{"orConditionList":[{"column":"S.S_SUPPLIER_NO","exp":"like","value":"00001"}]},{"column":"S.S_SUPPLIER_NO","orderType":"default","orderKey":"","direction":"DESC"}]', 'additionalParams':'{}' } s=requests.session() def login(s,loginData,data_search): try: response=s.post('http://******.com/portal/u/a/login.do',loginData) if response.status_code==200: print("login_success") except requests.ConnectionError as e: print('Error',e.args) def getjson(s,base_url,data_search): try: response=s.post(base_url,data_search) if response.status_code==200: #print("vendor_info_yes") return response.json() except requests.ConnectionError as e: print('Error',e.args) if __name__ == "__main__": ss=login(s,loginData,data_search) page=getjson(s,base_url,data_search) maxNum=math.ceil(page['total']/100) #计算出总的信息显示所需页面数 for pageNum in range(1,500): if pageNum==maxNum+1: wb.save(filename=pwd+u"\info_list.xlsx") #最后一页写完后,进行保存excel操作 end = time.time() time.sleep(2) sys.exit(0) data_search['page']=pageNum #修改字典的‘page’键对应值,逐页请求服务器数据 page=getjson(s,base_url,data_search) listlen=len(page['rows']) #由于最后一次得到的行数不见得是100行,所以需要动态获取列表长度,作为循环次数的依据。 for i in range(listlen): #对请求后得到的json文件进行解析,类似于字典,字典中含有列表,需要注意,当部分字段为空时,字典中部分元素可能不存在,需要判断字典。 sheet['A%d' %((pageNum-1)*100+i+2)].value = page['rows'][i]['supplierNo'] sheet['B%d' %((pageNum-1)*100+i+2)].value = page['rows'][i]['companyName'] if 'linkMan1' in page['rows'][i].keys(): sheet['C%d' %((pageNum-1)*100+i+2)].value = page['rows'][i]['linkMan1'] if 'phone1' in page['rows'][i].keys(): sheet['D%d' %((pageNum-1)*100+i+2)].value = page['rows'][i]['phone1'] if 'email1' in page['rows'][i].keys(): sheet['E%d' %((pageNum-1)*100+i+2)].value = page['rows'][i]['email1'] if 'legalRepresentative' in page['rows'][i].keys(): sheet['F%d' %((pageNum-1)*100+i+2)].value = page['rows'][i]['legalRepresentative'] if 'email2' in page['rows'][i].keys(): sheet['G%d' %((pageNum-1)*100+i+2)].value = page['rows'][i]['email2'] print(pageNum)   

    该程序还有一个可以完善的地方:就是封装后给用户使用时不够直观,需要利用Tkinter等制作简易gui进度条百分比及剩余时间展示。

  • 相关阅读:
    学生管理系统简化版
    图形用户界面编程——事件驱动编程
    图形界面编程
    集合框架
    多线程编程
    反射
    相关类
    异常(4.13)
    接口
    锁!代码锁
  • 原文地址:https://www.cnblogs.com/new-june/p/9225953.html
Copyright © 2020-2023  润新知