爬取航班数据

针对飞常准和航旅纵横,爬取航段+航班日期和航班号+航班日期数据
url飞常准:
航段
'http://webapp.veryzhun.com/h5/flightsearch?arr=%s&dep=%s&' \
'date=%s&token=根据自己的浏览器来' % (arr, dep, fData)
航班
'http://webapp.veryzhun.com/h5/flightsearch?fnum=%s&date=%s' \
'&token=小仙女的马赛克' % (fNo, fData)
arr:目的地 dep:出发地 fData:航班日期 fNo:航班号
航旅纵横:
航段
'http://www.umetrip.com/mskyweb/fs/fa.do?dep=' \
'%s&arr=%s&date=%s&channel=' % (arr, dep, fData)
航班
'http://www.umetrip.com/mskyweb/fs/fc.do?' \
'flightNo=%s&date=%s&channel=' % (fNo, fData)
爬取数据
飞常准的数据格式是json,返回一个数组,里面包含了航班的所有信息。 如果想知道某机场的所有航班信息情况,那么只用按照航段+航班日期来爬取就行了。(异常信息可以根据自己遇到的情况添加)
try:
html = urlopen(url).read().strip().decode("utf-8")
return json.loads(html)
except (HTTPError,URLError,AttributeError,
requests.exceptions.ReadTimeout,
requests.exceptions.ConnectionError,
json.decoder.JSONDecodeError) as e:
return ""
航旅纵横是html格式的,与飞常准不同的是,获取某机场航班所有信息,只能先爬取航段数据,得到该航段的所有航班号,再根据航班号查询。 (异常同上 这里简写)
html = urlopen(url)
bsObj = BeautifulSoup(html.read())
数据解析飞常准是标准的 json 格式,把数据直接入库就可以。航旅纵横的航班数据是用javascript渲染的,我用了比较不灵活的办法(用字符串分隔)。 接着对航班数据再进行一次 BeautifulSoup 处理,就可以得到span里的数据啦 复杂的这块代码就不粘贴了
验证码问题飞常准爬取次数>10 的时候,会出现请输入验证码。第一次的验证码就是纯图片,我机智的模拟输入111,–验证码有误 请重新输入。这次的验证码就正常了。
下载验证码首先得把验证码下载下来,才能识别不是。。
123456try: f = open("VerificationCode.jpg", 'wb') f.write(urlopen(picUrl).read()) f.close() except Exception as e: print(picUrl+" error")
识别验证码因为这个验证码比较简单,我就用pytesseract来识别了。验证码是数字+字母的组合,但有时候会识别到特殊符号导致出错,我就用正则表达式过滤掉了。
123image = Image.open("VerificationCode.jpg") yzm = pytesseract.image_to_string(image) yzm = re.sub('[^a-zA-Z0-9]',"",yzm)
封ip问题飞常准没爬几次验证码就出现了,之后再爬几次就封ip了。具体表现为:操作频繁。航旅纵横就比较友好了,我能爬很久,但就是数据不全。。我想要的它没有,不过航旅纵横的app里数据很全,厉害的人可以试着去爬app那么问题出现了,接下来代理ip上场。
代理ip我试过 讯代理 和 全网代理IP 这两个都还算稳定的,选择哪个主要还是看自己需求,挑个便宜的
讯代理的动态转发官方提供的代码很简单,就是把headers封装成他们的服务器
123456789101112131415def getAuth(): timestamp = str(int(time.time())) # 计算时间戳 string = "orderno=" + orderno + "," + "secret=" + secret + "," + "timestamp=" + timestamp if is_python3: string = string.encode() sign = hashlib.md5(string).hexdigest().upper() auth = "sign=" + sign + "&" + "orderno=" + orderno + "&" + "timestamp=" + timestamp return authdef getXundailiIp(): ip_port = ip + ":" + port auth = getAuth() proxy = {"http": "http://" + ip_port, "https": "https://" + ip_port} headers = {"Proxy-Authorization": auth} return headers,proxy
下了一个1块钱10000次订单。用起来不是特别稳定,不过影响不大。
全网代理IP我买了4小时的动态代理IP,每次接口返回一个IP,IP有效期1分钟。用起来也还不错。有时候响应的比较慢,我在请求的时候加了超时时间。这套代码就更简单啦
123456789101112131415161718def getProxyip(): # 这里填写全网代理IP提供的API订单号(请到用户中心获取) order = "小仙女的马赛克" # 获取IP的API接口 apiUrl = "http://dynamic.goubanjia.com/dynamic/get/" + order + ".html" try: # 获取IP列表 res = urlopen(apiUrl).read().strip() # 按照\n分割获取到的IP # ips = res.split("\n") # 随机选择一个IP # proxyip = random.choice(ips) # 使用代理IP请求目标网址 proxyip = res.decode(encoding="utf-8") return proxyip except Exception: return ""
因为我每次返回只有一个ip啦,不需要切割再随机选择一个
代码已上传到github https://github.com/pangrou/machine-learning/tree/master/scrape