1. 程式人生 > >Python 通過微信控制實現app定位傳送到個人伺服器,再轉發微信伺服器接收位置資訊。

Python 通過微信控制實現app定位傳送到個人伺服器,再轉發微信伺服器接收位置資訊。

考慮到女友的安全問題,就做了一個app實現定位和伺服器實現轉發的東西。剛學python,竟沒想到用物件程式設計會更加方便,全程過程式開發,程式碼有點臃腫,就當學習下python吧.效果就是:在微信公眾號中輸入指定字元比如:”我要知道你的位置”,手機那端的位置就彈出來了.主要是講一下思路:先是app實現定位,當微信傳送訊息時,訊息從微信伺服器轉發到開發者伺服器然後用socket傳送指定訊息來通知app,I need your location,app接收到訊息之後再發送給開發伺服器(app 開service實現後臺全程執行),由於定位資訊是經緯度,所以用了高德API,但是發現谷歌地球的定位是準的,可能和android內建的定位有關係吧,然後就轉換了一下不同地圖的經緯度,然後轉成位置資訊傳送給微信伺服器.

import socket
import threading
import os
import requests
from flask import Flask
from flask import request
from bs4 import BeautifulSoup
import json
global sock

#實現通過微信控制手機app定位傳送給伺服器顯示位置資訊

loca = "welcome"
app = Flask(__name__)

#搭建web伺服器通過socket傳送訊息給app索取定位資訊,然後轉發給微信伺服器
@app.route("/wx_check",methods=["POST","GET"]) #這裡用了一個Web框架   "/wx_check" 是你在微信中填的開發者伺服器路徑
def application(): openID = request.args['openid'] # 微信發的,詳見開發者文件 soup = BeautifulSoup(request.data,"html.parser") content = soup.find("content") # content 是微信使用者發的訊息,可用來驗證使用者 sock.send(b"getlocation") # 傳送資訊通知android global loca while True: #手動阻塞 if loca != "welcome"
: break back = loca loca = "welcome" return """ <xml> <ToUserName>%s</ToUserName> <FromUserName>qqmsssssssss</FromUserName> <CreateTime>12345678</CreateTime> <MsgType>text</MsgType> <Content>%s</Content> </xml>"""%(openID,back) def start(): app.run('0.0.0.0',80) threading.Thread(target=start,args=()).start() # 與app進行socket連線 接受定位資訊 另外用到經緯度相容轉換API 和經緯度轉位置API def tcplink(sock,addr): try: print('Accept new connection from %s:%s...' % addr) while True: sock.setblocking(True) data = sock.recv(1024) location = data.decode('utf-8') print("client:"+location) # 以下進行經緯度 地圖資訊的轉換 loca為app所在地址接上面的 堵塞 if location != "": global loca print(location) lis = location.split(",") location = "%s,%s"%(lis[1],lis[0]) print(location) xml = requests.get("http://api.gpsspg.com/convert/coord/?oid=xxxx&key=xxxxxxxxxxxxxxxxxx&from=0&to=3&latlng=%s&output=xml"%location) soup = BeautifulSoup(xml.text,"html.parser") print(soup.text) lat= soup.find("lat").string lng= soup.find("lng").string location = "%s,%s"%(lng,lat) print("after"+location) a = requests.get("http://restapi.amap.com/v3/geocode/regeo?key=xxxxxxxxxxxxxxxxx&location="+location) loca = a.text obj = json.loads(loca) loca = obj["regeocode"]["formatted_address"] else: print("socket is close,waiting new accept") sock.close() break except Exception as e: location = "raise error" finally: pass try: s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.bind(('0.0.0.0',9999)) s.listen(10) print('waiting to connect') while True: sock,addr = s.accept() #等待app來連線 t = threading.Thread(target=tcplink,args=(sock,addr)) t.start() finally: print("ending")

以下是android端程式碼:

# 獲取定位,其實就是獲取經緯度
private Location getLastKnownLocation() {
        LocationManager mLocationManager = (LocationManager)getApplicationContext().getSystemService(LOCATION_SERVICE);
        List<String> providers = mLocationManager.getProviders(true);
        Location bestLocation = null;
        for (String provider : providers) {
            Location l = mLocationManager.getLastKnownLocation(provider);
            if (l == null) {
                continue;
            }
            if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
                // Found best last known location: %s", l);
                bestLocation = l;
            }
        }
        return bestLocation;
    }


    String provider;
    public void GetLocation(){
        LocationManager mLocationManager;
        Location location = getLastKnownLocation();


//        Log.d("TAG", provider.toString());
        Log.d("TAG", location.toString());
        if (location != null) {
            //獲取當前位置,這裡只用到了經緯度
            String string =location.getLongitude() + ","+ location.getLatitude();
            try {
                OutputStream outputStream = socket.getOutputStream();
                PrintWriter writer = new PrintWriter(outputStream);
                writer.write(string);
                writer.flush();
//              writer.close();
//              socket.shutdownOutput();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

    @SuppressLint("ShowToast") public void Connect(){
        try {
            socket = new Socket();
            socket.connect(new InetSocketAddress("xxx.xxx.xxx.xxx",9999));
            while (true) {
                Log.d("TAG", socket.isConnected()+"");
                InputStream stream = socket.getInputStream();  
                byte[] b = new byte[11];
                stream.read(b);
                String sb = new String(b);
                if(sb.equalsIgnoreCase("getlocation")){
                    GetLocation();
                }else
                {
                    OutputStream outoStream = socket.getOutputStream();
                    outoStream.write("error code".getBytes());
                    socket.shutdownOutput();
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            Log.d("TAG", "error");
            e.printStackTrace();
        }
    }