鱼C论坛

 找回密码
 立即注册
查看: 5383|回复: 17

[技术交流] 鱼C论坛Python精英挑战赛(第三季01期)

[复制链接]
发表于 2017-9-3 22:55:49 | 显示全部楼层 |阅读模式
本帖最后由 jerryxjr1220 于 2017-9-11 11:28 编辑

第三届鱼C论坛精英挑战赛开赛咯!为了增加趣味性,本届比赛增加了“新玩法”-- “押宝玩法”,“竞猜玩法”和“擂主玩法”。

规则:

1. 押宝玩法:进入“押宝”竞猜帖,购买主题(5鱼币)参与“押宝”,最终“押宝”获胜者将平分奖池的奖金并额外获取10鱼币奖励。猜错者将不返还“押宝”的鱼币。若本届比赛无人“押宝”成功,奖金将累计到下次比赛。

2. 竞猜玩法:直接在比赛帖的下方进行投票,凡事“竞赛”获胜者,将奖励5鱼币。竞猜无门槛,人人都可以参与。竞猜以后,请在本帖留个言,方便领取奖励。

3. 擂主玩法:上一期挑战成功的鱼油成为挑战赛的擂主,擂主有优先权提议下一期的赛题,一届挑战赛共分5期,同一届中当擂主最长的鱼油有额外奖励。

本期擂主:@小锟

本期赛题由擂主提议:爬虫题


题目:违章查询

登录 http://www.weizhangwang.com 可以进行违章信息的查询。

输入信息:

无标题1.png

输入验证码:

无标题2.png

返回查询信息:

无标题3.png

现在请设计爬虫程序,用户输入信息后,程序返回验证图片并显示:

无标题4.png

用户输入验证码后返回查询信息:
def weizhang(省份, 地名, 车牌号, 车辆类型, 发动机号后6位, 车架号后6位):
    '''Your code here'''
    显示验证图片,并请求输入验证码。
    return 查询信息 (#恭喜你,你的车辆没有非现场(电子眼)违章记录!)
    如果输入信息有误,return 'N/A'

要求

程序执行正确,代码简洁优雅。尽量避免用selenium模拟浏览器操作。


加分题

实现机器自动识别验证码,并返回输入验证码后的查询信息。


比赛截止日期:9月8日24时,竞猜和押宝截止日期为9月7日

@小甲鱼 @冬雪雪冬 @~风介~ @SixPy


单选投票, 共有 43 人参与投票
您所在的用户组没有投票权限

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-4 00:52:01 | 显示全部楼层
支持支持!我重新排版了一下,看着是不是清爽多了~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-9-4 07:13:45 From FishC Mobile | 显示全部楼层
小甲鱼 发表于 2017-9-4 00:52
支持支持!我重新排版了一下,看着是不是清爽多了~

棒棒哒!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-4 11:38:06 | 显示全部楼层
我只围观不说话
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-4 15:27:20 | 显示全部楼层
66666666666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-4 21:34:54 | 显示全部楼层
我是不是不用再押注了,要是需要就压小锟
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-5 09:39:37 | 显示全部楼层
本帖最后由 小锟 于 2017-9-6 12:12 编辑

验证码在附件,请解压后放到C:\Users\Administrator\Desktop
因为图片处理的时候没有去掉曲线,所以经常会预测T,以及有横线的字母,以及k和x的不好分辨,最后加上字符串的切割的问题(我只是用np.array_split切割的)
测试了下准确率,单个字母为0.75 ,四个的话为0.35
#登陆失败的原因可能是验证码输入不正确,请看以下验证码和预测的是否一样
#如果出现index找不到的情况,是因为存放城市信息的js文件没有响应,再运行下就好
import requests
import os
os.chdir(r'C:\Users\Administrator\Desktop\checkcode')
import re
import urllib
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from sklearn.feature_selection import VarianceThreshold
from sklearn import svm

#将验证码变成四个向量
def split_checkcode(one):
    for i in range(32 - one.shape[1]):
        if i % 2 :
            one = np.hstack( (  np.array([1]*40)[:,np.newaxis] ,one ) )
        else :
            one = np.hstack( (  one , np.array([1]*40)[:,np.newaxis]  ) )
    one = one.ravel()[np.newaxis,:]
    return one
#处理验证码
def checkcode_process(image):
    image = Image.open(image).convert('L')
    image_np = np.array(image)
    means = image_np.mean()
    rows , cols = image_np.shape
    for row in range(rows):
        for col in range(cols) :
            if image_np[row,col] < means:
                image_np[row,col] = 0
            else:
                image_np[row,col] = 1
    for i in range(1,rows-1):
        for j in range(1,cols-1) :
            num = 0
            if image_np[i - 1,j]:num +=1
            if image_np[i + 1,j]:num +=1
            if image_np[i,j - 1]:num +=1
            if image_np[i,j + 1]:num +=1
            if num >= 3 :
                    image_np[i,j] = 1
    for col in range(cols):
        if len(np.where(image_np[:,col] == 0)[0]) <= 5:
            image_np[:,col] = 1
    select = VarianceThreshold(0.11)
    new_image_np = select.fit_transform(image_np)
    all_np = np.array_split(new_image_np,4,axis=1)
    #Image.fromarray(all_np[0])
    new_g = [split_checkcode(i) for i in all_np]
    vector = np.vstack(new_g)
    return vector
#将所有验证码放一起训练
x = []
for item in range(100):
    image = str(item) + '.png'
    vector = checkcode_process(image)
    x.append(vector)
x = np.vstack( [x[i] for i in range(100)] )

class_ = 'QWERTYUIOPASDFGHJKLZXCVBNM'
y_class = {i : class_[i]for i in range(26)}
y_class2 = {class_[i] : i for i in range(26)}
str1 = ''
with open('1.txt', 'r') as f :
    for i in f.readlines():
        str1 += i
y = str1.replace('\n','')
new_yy = [y_class2[i] for i in y]
svc = svm.SVC(gamma=0.001,C=100)
svc.fit(x[:],new_yy[:])


#爬虫部分
def crawl(province ,cityname,cphm,hpzl_text,enginenumber ,classnumber):
    data = {}
    #用户输入的部分
    data['province'] = province
    data['cityname'] = cityname
    data['cphm'] = cphm
    data['hpzl_text'] = hpzl_text
    data['enginenumber'] = enginenumber
    data['classnumber'] = classnumber
    #默认
    data['province_id'] = 'undefined'
    data['id360'] = '200'
    data['sourceline'] = 'js'
    data['classlen'] = len(data['classnumber'])
    data['enginelen'] = len(data['enginenumber'])
    header ={
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0'
            }
    #省份区号都在js文件中
    city_new = requests.get(r'http://static.weizhangwang.com/js/cityinfo_all.js?v=20178420' ,headers = header)
    city_new.encoding = 'utf-8'
    city_text = city_new.text
    all_city = city_text.split('|')[1:-1]
    all_city = [i.split(',') for i in all_city]
    every_city = [[]for i in all_city]
    for i in range(len(all_city)) :
        for j in all_city[i] :
            if j:
                every_city[i].append(j)
    for i ,j in enumerate(every_city):
        if data['cityname'] in j :
            index = i
            break
    #在开始的网页源代码中,直接自己建立
    hpzl = {'大型汽车' : '01' , '小型汽车':'02' , '使馆汽车':'03' , '领馆汽车':'04' ,
    '境外汽车' : '05' , '外籍汽车' : '06','两、三轮摩托车' : '07','轻便摩托车' : '08','使馆摩托车' : '09','领馆摩托车' : '10',
    '境外摩托车' : '11','外籍摩托车' : '12','低速车' : '13','拖拉机' : '14','挂车' : '15','教练汽车' : '16','教练摩托车' : '17',
    '临时入境汽车' : '20','临时入境摩托车' : '21','临时行驶车' : '22','警用汽车' : '23','警用摩托' : '24','其它' : '99'
            }
    #也在一个js文件中,直接自己建立
    pid = {
    '贵':1,'豫':2,'鲁':3,'川':4,'苏':5, '青':6,'新':7, '闽':8,'浙':9, '鄂':10,
    '藏':11,'粤':12,'云':13,'京':14,'陕':15,'甘':16,'冀':17,'吉':18,'宁':19,
    '湘':20,'皖':21,'蒙':22,'沪':23,'晋':24,'琼':25,'辽':26,'渝':27,
    '黑':28,'津':29,'桂':31,'赣':30
    }
    #剩余要post的内容
    data['province_sn'] = every_city[index][3]
    data['city_sn'] = every_city[index][4]
    data['c_id'] = every_city[index][0]
    data['hpzl'] = hpzl[data['hpzl_text']]
    data['areacode'] = every_city[index][5]
    data['city_id'] = every_city[index][6]
    data['pid'] = str(data['province_sn'])
    data['jhcc'] = every_city[index][8]
    data['km_jgjId'] = every_city[index][13]
    data['sjb_carorg'] = every_city[index][13]
    data['js_carorg'] = every_city[index][13]


    sess = requests.session()
    r = sess.post(r'http://www3.weizhangwang.com/queryallcar_2.php',headers = header , data=data)
    r.encoding = 'utf-8'
    carIntNO = re.findall(r'carIntNO=(.*?)&',r.text)[0]

    check = sess.get(r'http://www3.weizhangwang.com/mysource/validatecode/code_gg.php',headers = header)
    with open('101.png','wb') as f:
        f.write(check.content)



    vector = checkcode_process('101.png')
    code = [y_class[i] for i in svc.predict(vector)]
    code = ''.join(code)
    print(code)

    #code = input('checkcode:')
    #把省份编码成网址的部分
    provience = urllib.parse.quote(data['province'])
    codeurl = 'http://www3.weizhangwang.com/mysource/validatecode/chk_code_new.php?act=gg&carIntNO='+carIntNO+\
              '&carCode=' + data['classnumber'] +\
              '&carCodeLen=' + str(len(data['classnumber']))  +\
              '&carEngineCode=' + data['enginenumber'] +\
              '&carEngineCodeLen=' + str(len(data['enginenumber'])) +\
              '&c_id=' + data['c_id']   + \
              '&sourceLine=js' +\
              '&refer=weizhangwang'  +\
              '&city=' + data['jhcc'] + \
              '&km_jgjId='  + data['km_jgjId'] +\
              '&js_carorg=' + data['km_jgjId'] +\
              '&province=' + provience

    code_post = sess.post(codeurl , data={'code':code} ,headers =header)
    text = code_post.text
    #这里最坑了,一定要字符串处理,不然就进去的,我找了好久这个才登陆成功
    text = text.replace('%','%25')
    url = 'http://www3.weizhangwang.com/mysource/querywzjson_code.php?k=' +  \
            text + '&flag=-1'
    #print(url)
    result = sess.get(url , headers = header)
    result.encoding = 'utf-8'
    #print(result.text)

    text1 = eval(result.text)
    finally_str = text1['result_table']
    result_str = re.findall(r'>(.*?)<',finally_str)[0]
    if result_str:
        return  result_str if '恭喜' in result_str else 'N/A'
    else:
        return re.findall(r'<b>(.*?)<',finally_str)[0]


print(crawl('广东','深圳','F7638','大型汽车','144528','530080'))

checkcode.rar

406.69 KB, 下载次数: 1

验证码

点评

我很赞同!: 5.0
我很赞同!: 5
除去验证码自动识别部分,其余部分的执行都是正确的。 验证码自动识别需要安装sklearn模块,不知道为啥我的机器上一直有问题...  发表于 2017-9-5 15:47

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +5 收起 理由
jerryxjr1220 + 5 + 5 + 5 答题奖励,辛苦了,直接挑战最高难度!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-5 16:02:42 | 显示全部楼层
本帖最后由 小锟 于 2017-9-5 16:21 编辑
小锟 发表于 2017-9-5 09:39
验证码在附件,请解压后放到桌面
因为图片处理的时候没有去掉曲线, ...


我也不知道,我用的是anaconda3.6版本的,是不是没有下载验证码的附件啊,我看下载次数为0
附上一张在IPYTHON成功识别的照片
捕获.PNG

点评

我很赞同!: 5.0
另外,建议把返回的结果用re处理一下,提取关键信息即可。  发表于 2017-9-6 09:23
我很赞同!: 5
我是sklearn模块安装有问题,sklearn无法导入。你的程序可能是对的,只是我无法测试。  发表于 2017-9-6 09:22

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +5 收起 理由
jerryxjr1220 + 5 + 5 + 5 支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-6 16:36:08 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-10 10:13:20 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-11 20:22:22 | 显示全部楼层
小锟 发表于 2017-9-5 09:39
验证码在附件,请解压后放到C:%users\Administrator\Desktop
因为图片处理的时候没有去掉曲线,所以经常会 ...

求抓包分析过程,爬虫学的不好
点查询的时候抓包抓了这么个东西
捕获.PNG
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-12 08:36:38 | 显示全部楼层
小剑剑 发表于 2017-9-11 20:22
求抓包分析过程,爬虫学的不好
点查询的时候抓包抓了这么个东西

我是先发现最后查询的结果没有在网页源代码中显示,所以我在F12中找了一下JS加载的文件,找到了一个没经过编码的文件,复制到Python中显示的是结果,说明最后的结果是在这个文件中的,看一下这个网址,一大串很长,然后分析它是怎么来的,发现它验证码验证之后产生的内容,但是要经过字符串处理。最后分析POST内容在哪就好了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-13 09:09:43 | 显示全部楼层
本帖最后由 小锟 于 2017-9-13 09:11 编辑

图片内容有点乱,不是我的本意啊,鼠标移动到图片上,可以看到附加说明

小剑剑 发表于 2017-9-11 20:22
求抓包分析过程,爬虫学的不好
点查询的时候抓包抓了这么个东西


详细的我也不能说出来了,只能简单的说下,
.post的文件

登陆后刷新一下,前三个js里面

登陆后刷新一下,前三个js里面

汽车类型

汽车类型


.

刷新下验证码,得到验证吗的网站

刷新下验证码,得到验证吗的网站

得到内容的网站

得到内容的网站





可能会有不同,我也是重复登陆,不断刷新一步步得到的,大体的是这样

找到post请求的网站

找到post请求的网站

网址哪里来的,要仔细对比哦

网址哪里来的,要仔细对比哦

要得到的内容

要得到的内容

点评

我很赞同!: 5.0
我很赞同!: 5
赞!  发表于 2017-9-13 11:29
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-13 12:58:43 | 显示全部楼层
小锟 发表于 2017-9-13 09:09
图片内容有点乱,不是我的本意啊,鼠标移动到图片上,可以看到附加说明

感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-24 14:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表