鱼C论坛

 找回密码
 立即注册
查看: 4870|回复: 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

用户输入验证码后返回查询信息:

  1. def weizhang(省份, 地名, 车牌号, 车辆类型, 发动机号后6位, 车架号后6位):
  2.     '''Your code here'''
  3.     显示验证图片,并请求输入验证码。
  4.     return 查询信息 (#恭喜你,你的车辆没有非现场(电子眼)违章记录!)
  5.     如果输入信息有误,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

  1. #登陆失败的原因可能是验证码输入不正确,请看以下验证码和预测的是否一样
  2. #如果出现index找不到的情况,是因为存放城市信息的js文件没有响应,再运行下就好
  3. import requests
  4. import os
  5. os.chdir(r'C:\Users\Administrator\Desktop\checkcode')
  6. import re
  7. import urllib
  8. import numpy as np
  9. from PIL import Image
  10. import matplotlib.pyplot as plt
  11. from sklearn.feature_selection import VarianceThreshold
  12. from sklearn import svm

  13. #将验证码变成四个向量
  14. def split_checkcode(one):
  15.     for i in range(32 - one.shape[1]):
  16.         if i % 2 :
  17.             one = np.hstack( (  np.array([1]*40)[:,np.newaxis] ,one ) )
  18.         else :
  19.             one = np.hstack( (  one , np.array([1]*40)[:,np.newaxis]  ) )
  20.     one = one.ravel()[np.newaxis,:]
  21.     return one
  22. #处理验证码
  23. def checkcode_process(image):
  24.     image = Image.open(image).convert('L')
  25.     image_np = np.array(image)
  26.     means = image_np.mean()
  27.     rows , cols = image_np.shape
  28.     for row in range(rows):
  29.         for col in range(cols) :
  30.             if image_np[row,col] < means:
  31.                 image_np[row,col] = 0
  32.             else:
  33.                 image_np[row,col] = 1
  34.     for i in range(1,rows-1):
  35.         for j in range(1,cols-1) :
  36.             num = 0
  37.             if image_np[i - 1,j]:num +=1
  38.             if image_np[i + 1,j]:num +=1
  39.             if image_np[i,j - 1]:num +=1
  40.             if image_np[i,j + 1]:num +=1
  41.             if num >= 3 :
  42.                     image_np[i,j] = 1
  43.     for col in range(cols):
  44.         if len(np.where(image_np[:,col] == 0)[0]) <= 5:
  45.             image_np[:,col] = 1
  46.     select = VarianceThreshold(0.11)
  47.     new_image_np = select.fit_transform(image_np)
  48.     all_np = np.array_split(new_image_np,4,axis=1)
  49.     #Image.fromarray(all_np[0])
  50.     new_g = [split_checkcode(i) for i in all_np]
  51.     vector = np.vstack(new_g)
  52.     return vector
  53. #将所有验证码放一起训练
  54. x = []
  55. for item in range(100):
  56.     image = str(item) + '.png'
  57.     vector = checkcode_process(image)
  58.     x.append(vector)
  59. x = np.vstack( [x[i] for i in range(100)] )

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


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


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

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



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

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

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

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


  173. 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-4-20 14:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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