宝宝小爬虫Selenium自动获取网页cookie+Curl数据查询

宝宝小爬虫Selenium获取网页cookie+Curl数据查询

作者的自言自语:我们在获取网页数据的时候,遇到某些网站往往需要登陆成功后才有我们想要的数据,这个时候我们就需要获得网页的cookie,如果每次都要自己打开网页复制cookie出来保存那太麻烦啦,所以我用selenium自动打开网页模拟。
我们要干的事情
1.selenium模拟打开网页,输入用户名,密码
2.登陆成功后获取cookie,保存为json
3.scrapy利用保存好的json读取cookie,爬取网页信息

Selenium

Selenium作为python的一个网页模拟,可以操作众多的网页类型,这里我使用的chromedriver作为演示。需要条件
1.google浏览器
2.chromedriver.exe
我们来实战,以登陆友盟为例:

# -*- coding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import os
import time
import json
import traceback
from selenium import webdriver
# 这个函数的意思是去试着寻找指定的元素 尝试200次,每次间隔一秒
def TryUntilFind(driver,element,findway='find_element_by_xpath',findTime=1):
    time.sleep(0.5)
    if findTime > 200:
        return 'Can\'t find'
    try:
        func = 'driver.%s(element)'%findway
        return eval(func)
    except Exception as e:
        time.sleep(0.5)
        return TryUntilFind(driver,element,findway,findTime+1)

# 启动google浏览器,自动登录友盟
def UmengLogin(username,password):
    tmp_time = time.time()
    driver   = webdriver.Chrome()
    # pass
    result   = u'error: --刚开始启动--'
    try:
        # 打开友盟的登陆网站
        driver.get('https://i.umeng.com/')
        time.sleep(0.5)
        # 找到用户名输入框,输入用户名
        TryUntilFind(driver,'//*[@id="ump"]/div[1]/div/form/div[1]/ul/li[1]/div/label/input').send_keys(username)
        # 找到密码输入框 输入密码
        TryUntilFind(driver,'//*[@id="ump"]/div[1]/div/form/div[1]/ul/li[2]/label/input').send_keys(password)
        # 点击登陆
        TryUntilFind(driver,'//*[@id="submitForm"]').click()
        time.sleep(0.5)
        # 检验是否登陆成功,成功后会跳转到指定网页,根据网页url是否转变了来判断
        if driver.current_url != r"https://i.umeng.com/user/products":
            time.sleep(1)
            if driver.current_url != r"https://i.umeng.com/user/products":
                raise Exception(u'登陆失败')
        # 登陆成功后再随意打开个这个网页的子页面 就可以收集cookie了
        driver.get('http://mobile.umeng.com/apps/get_summary_data')
        time.sleep(0.5)
        cookie    = [item["name"] + "=" + item["value"] for item in driver.get_cookies()] 
        cookiestr = ';'.join(item for item in cookie)  
        # 我保留了三个字段 执行用的总时间-usetime  获取的cookie-cookie  现在的时间-now  
        result    = {'usetime':str(time.time()-tmp_time),'cookie':cookiestr,'now':time.time()}
    except Exception, e:
        traceback.print_exc(file=open(os.path.join(sys.path[0],'err.txt'),'w'))
        err       = open('err.txt').read()
        result    = 'error: '+err
    finally:
        driver.quit()
    return result


if __name__ == '__main__':
    username = u'用户名'
    password = u'密码'
    result   = UmengLogin(username,password)
    if 'error:' not in result:
        json.dump(result,open('umeng.json','wb'))
    else:
        # 如果有错误 报出错误
        print(result)

可能遇到的错误
这里写图片描述
1.提示找不到chromedriver那么就去,错误所提示的网站下载最新版的chromedriver驱动,放置到环境变量Path有配置的位置,我的定制环境也有放置一个chromedriver.exe 放在Python27\Scripts里面
2.如果你简单的使用driver.get(‘xxx网站’)的时候网页崩溃了,那么估计是你的chromediver版本过低找个合适的就好了
3.如果用户名密码错误,那么你该检验下自己有没有自己可以登陆使用的账户了
简单解释一下上面的代码: 使用Selenium的webdriver模块可以启动google浏览器(driver = webdriver.Chrome())–打开指定网页(driver.get(网页地址))–找到账户密码输入框(driver.find_element_by_xpath(‘怎么获取是吧,浏览器右键你想找的元素-检查-Copy Xpath就找到了’))-登陆成功后再随便打开一个子页面,这时候网页的cookie就能用了

Curl数据查询

打开友盟网页 随便打开一款我们的产品
这里写图片描述
通过network的监控,我们会发现 自定义事件的所有数据都是通过一个网页接口请求得到的
So:,后面我们打算不登录友盟了,我们全部数据可以通过这个接口直接查询不就可以了得到了
这里写图片描述
右键Copy as cURL(bash)
把复制得到的curl保存为到txt,通过比较两款不一样的产品的curl可以发现,不同产品之间的差别只有

curl 'http://mobile.umeng.com/apps/628100426be85e76a38f0955/events/load_table_data?page=1&per_page=30&versions%5B%5D=&stats=count&show_all=false'

网页链接apps/~/events中间值的区别,这个值通过前一个页面-应用列表就可以得到我们所有产品的app-id
so:如果我们要查询我们所有产品的自定义事件,先在http://mobile.umeng.com/apps?show_all=true 获取所有产品的appid,然后通过拼接curl就可以查询所有数据啦,怎么获取我们所有产品呢?
方法一:通过Selenium遍历所有页面,把信息存进表里记录下来
方法二:分析这个show_all网址,发现所有的产品数据都是通过一个请求就全部获取了,保存这个curl,以后都这么获取所有产品的列表
这里写图片描述
我们把curl做成一个模板,原app-id用Replace_App_Id替换,原cookie用Replace_Cookie替换,保存为tmple.txt

curl 'http://mobile.umeng.com/apps/Replace_App_Id/events/load_table_data?page=1&per_page=30&versions%5B%5D=&stats=count&show_all=false' -H 'Cookie: Replace_Cookie' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'X-CSRF-Token: cOZgtNh6TDw+PHC/ClrbrkySOdKEcNbrqrCslHK5J/k=' -H 'Accept-Language: zh-CN,zh;q=0.8' -H 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Referer: http://mobile.umeng.com/apps/Replace_App_Id/events/dashboard' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --compressed

这就是一个curl模板
接下来我们要指定appid查询数据

# -*- coding:utf-8 -*-
import os
import json
cookie_dic = json.load(open('umeng.json'))

tmple = open('tmple.txt').read()
tmple = tmple.replace('Replace_App_Id','628100426be85e76a38f0955')
curl  = tmple.replace('Replace_Cookie',cookie_dic['cookie'])
print curl

怎么验证打印出来的这个curl能不能用呢?
mac电脑可以直接在终端输入这个curl就可以查询到数据了,由于我用的是Windows电脑所以只能借助其它linux电脑来查询,这里我用的Xshell,使用Xshell链接上我的mac电脑
这里写图片描述
从图中可以发现,通过替换appid和cookie值可以查询到准确的数据
但是如果我就是用的Windows电脑不想换了,我想直接代码查询呢?
可以通过python的paramiko模块,远程登录linux服务器得到,那么就省得开Xshell了

# -*- coding:utf-8 -*-
def create_ssh(username, password, ip, port=22):
    """
    创建ssh连接
    :param username: 用户名
    :param password: 密码
    :param ip: ip地址
    :param port: 端口
    :return: ssh连接客户端
    """
    import paramiko
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(ip, port, username, password)
    return ssh

def usecmd(ssh_client, code):
    # 在远程终端执行命令
    stdin, stdout, stderr = ssh_client.exec_command(
"""
%s
"""%(code))
    return stdout.read(), stderr.read()

if __name__ == '__main__':
    IP_Port = 'linux电脑的ip地址'
    ssh     = create_ssh('linux电脑用户名','linux电脑密码',IP_Port,打开的远程连接共享端口)
    curl    = "你的curl命令"
    out,err = usecmd(ssh,
"""
%s
"""%curl)
    ssh.close()
    print(out)
    print('--------------')
    print(err)

同理的,我们的产品数也会每天在增加,所以我们只需要Selenium获取cookie这个方法放在一台固定的机子上(我就放在我的常年开机的mac上的django),然后拼接获取到的cookie和获取所有产品的curl就能得每天

So: cookie是会有过期时间的,这就是为什么我前面讲到用Selenium自动获取cookie,并记录了一个当时的时间-now,假设友盟的过期时间为1小时,那么下次我获取cookie的时候就用当时的时间-now,如果>3600秒那么重新获取cookie,否则直接用已经获取的cookie
![enter description here][6]
所以现在我们做到了
1.通过Selenium获取cookie
2.在应用列表页面找到查询我的应用列表的接口,保存curl bash,并改造为模板,方便替换cookie查询我的所有应用
3.通过第二步我已经获得了所有应用的appid,在点击我的随意一款应用,查询自定义事件,保存curl bash,并改造为模板,通过替换appid和cookie就可以查询得到我想要的自定义事件了
4.后面我们会介绍到django,也就是以上的操作都可以挂到一台服务器自动完成,你只需要访问开出来的接口等结果就可以了

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值