NiceLeeのBlog 用爱发电 bilibili~

Python 微博位置小尾巴

2020-12-16
nIceLee

阅读:


如何伪装微博位置前文有讲,但还是挺麻烦的。
现在尝试简化一下,配合vercel进行适配。

先看效果

https://tools.nicelee.top/api/weibo/?key=纽约&index=0

HTTPServer版本

from http.server import BaseHTTPRequestHandler, HTTPServer
import requests
import re
from urllib.parse import quote


'''
通过关键词查询可用位置信息
'''
def getContainerInfo(keyWord, index = 0):
    url = "https://place.weibo.com/wandermap/search2?keyword=" + quote(keyWord)
    headers = {
        'Host': 'place.weibo.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'Content-Type': 'application/x-www-form-urlencoded',
        'X-Requested-With': 'XMLHttpRequest',
        'Referer': 'https://place.weibo.com/',
        'Connection': 'keep-alive',
    }
    data = requests.get(url, timeout=10, headers=headers).json()
    lbs_list = data["pois"]
    lbs = lbs_list[index]
    return lbs_list, getContainerInfoFromLbsInFo(lbs["poiid"], lbs["lon"], lbs["lat"])
    '''
    for lbs in lbs_list:
        #print(lbs["address"])
        data = getContainerInfoFromLbsInFo(lbs["poiid"], lbs["lon"], lbs["lat"])
        print(data)
        jj = getWeibos(data["containerid"])
        for card in jj["data"]["cards"]:
            for item in card["card_group"]:
                if "mblog" in item:
                    #print(item["mblog"]["raw_text"])
                    print(item["mblog"]["text"])
                else:
                    break;
        break;
    '''
'''
通过lbs信息查询可用位置信息
''' 
def getContainerInfoFromLbsInFo(lbsId, lon, lat):
    ext = '{"lbsType":"poi","lbsID":"%s"}'%lbsId
    ext = quote(ext)
    url = 'https://place.weibo.com/wandermap/paras?ext=%s&lng=%s&lat=%s'%(ext, lon, lat)
    headers = {
        'Host': 'place.weibo.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'Content-Type': 'application/x-www-form-urlencoded',
        'X-Requested-With': 'XMLHttpRequest',
        'Referer': 'https://place.weibo.com/',
        'Connection': 'keep-alive',
    }
    data = requests.get(url, timeout=10, headers=headers).json()
    return data

    
'''
通过container_id查询相关微博
''' 
def getWeibos(container_id):
    url = 'https://m.weibo.cn/api/container/getIndex?containerid=' + container_id
    headers = {
        'Host': 'm.weibo.cn',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
        'Accept': 'application/json, text/plain, */*',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'MWeibo-Pwa': '1',
        'X-Requested-With': 'XMLHttpRequest',
        'Referer': 'https://m.weibo.cn/p/cardlist?extparam=&containerid=' + container_id,
        'Connection': 'keep-alive',
    }
    data = requests.get(url, timeout=10, headers=headers).json()
    return data
    
class handler(BaseHTTPRequestHandler):

  def do_GET(self):
    self.send_response(200)
    self.send_header('Content-type', 'text/html; charset=utf-8')
    self.end_headers()
    
    try:
        path = str(self.path)
        searchObj = re.search(r"key=([^&]*)", path)
        if searchObj:
            keywords = searchObj.group(1)
        else:
            self.wfile.write(str("请携带参数key(地点关键词,必选)和index(可选)<br/>").encode())
            return
            
        searchObj = re.search(r"index=([^&]*)", path)
        if searchObj:
            index = int(searchObj.group(1))
        else:
            index = 0
        print(path)
        print(keywords)
        lbs_list, data = getContainerInfo(keywords, index)
        
        #列出相关地点
        i = 0
        for lbs in lbs_list:
            self.wfile.write(str(str(i) + "  ").encode())
            self.wfile.write(str(lbs["address"]).encode())
            self.wfile.write(str("<br/>").encode())
            i = i+1
        
        self.wfile.write(str("<br/>").encode())
        intro = "当前为地点%d %s 的相关微博"%(index, lbs_list[index]["address"])
        self.wfile.write(str(intro).encode())
        self.wfile.write(str("<hr/>").encode())
        
        #列出对应地点的相关微博
        cards = getWeibos(data["containerid"])
        for card in cards["data"]["cards"]:
            for item in card["card_group"]:
                if "mblog" in item:
                    mblog = item["mblog"]
                    searchObj = re.search(r'data-url="([^"]*)".*?timeline_card_small_location_default.*?<span class="surl-text">(.*?)</span>', mblog["text"])
                    if searchObj:
                        loc_url = searchObj.group(1)
                        loc_name = searchObj.group(2)
                        self.wfile.write(str(loc_name).encode())
                        self.wfile.write(str("&nbsp;&nbsp;&nbsp;&nbsp;").encode())
                        self.wfile.write(str(loc_url).encode())
                        self.wfile.write(str("<br/>").encode())                    
                    self.wfile.write(str(mblog["raw_text"]).encode())
                    self.wfile.write(str("<br/>-----------------------<br/>").encode())
                else:
                    break;
        return
    except Exception as e:
        self.wfile.write(str(e).encode())
        return
if __name__ == "__main__":
    http_server = HTTPServer(('', int(8888)), handler)
    http_server.serve_forever() 

Flask版本

渲染模板

<!doctype html>
<title>微博地点搜索</title>

<div>
{% for lbs in lbs_list %}
<p>{{ loop.index0 }}  {{ lbs.address }}</p>
{% endfor %}
</div>

<div>
<br/>
当前为地点{{ index }} {{ lbs_list[index].address }} 的相关微博
<hr/>

    {% for mblog in mblogs %}
    <div>
    {{ mblog.loc_name }}&nbsp;&nbsp;&nbsp;&nbsp;{{ mblog.loc_url }}
    <br/>
    {{ mblog.raw_text }}
    <br/>
    -----------------------
    <br/>
    </div>
    {% endfor %}

</div>
from flask import Flask, Response, request, render_template
from urllib.parse import quote
import requests
import re

app = Flask(__name__)


@app.route('/api/weibo/')
def catch_weibo():
    print(request.args)
    keywords = request.args.get('key')
    if not keywords:
        return Response("<h1>Error</h1>请携带参数key(地点关键词,必选)和index(可选)<br/>", mimetype="text/html")
        
    index = request.args.get('index')
    if index:
        index = int(index)
    else:
        index = 0

    lbs_list, data = getContainerInfo(keywords, index)
    
    mblogs = []
    #列出对应地点的相关微博
    cards = getWeibos(data["containerid"])
    for card in cards["data"]["cards"]:
        for item in card["card_group"]:
            if "mblog" in item:
                mblog = item["mblog"]
                searchObj = re.search(r'data-url="([^"]*)".*?timeline_card_small_location_default.*?<span class="surl-text">(.*?)</span>', mblog["text"])
                if searchObj:
                    mblog["loc_url"] = searchObj.group(1)
                    mblog["loc_name"] = searchObj.group(2)
                mblogs.append(mblog)
            else:
                break;
    return render_template('weibo.html', index = index, key = keywords,lbs_list = lbs_list, mblogs = mblogs)

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
    print(request.args)
    key = request.args.get('key')
    return Response("<h1>Flask</h1><p>You visited: /%s</p><p>key=%s</p>" % (path,key), mimetype="text/html")


    
    

'''
通过关键词查询可用位置信息
'''
def getContainerInfo(keyWord, index = 0):
    url = "https://place.weibo.com/wandermap/search2?keyword=" + quote(keyWord)
    headers = {
        'Host': 'place.weibo.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'Content-Type': 'application/x-www-form-urlencoded',
        'X-Requested-With': 'XMLHttpRequest',
        'Referer': 'https://place.weibo.com/',
        'Connection': 'keep-alive',
    }
    data = requests.get(url, timeout=10, headers=headers).json()
    lbs_list = data["pois"]
    lbs = lbs_list[index]
    return lbs_list, getContainerInfoFromLbsInFo(lbs["poiid"], lbs["lon"], lbs["lat"])
    '''
    for lbs in lbs_list:
        #print(lbs["address"])
        data = getContainerInfoFromLbsInFo(lbs["poiid"], lbs["lon"], lbs["lat"])
        print(data)
        jj = getWeibos(data["containerid"])
        for card in jj["data"]["cards"]:
            for item in card["card_group"]:
                if "mblog" in item:
                    #print(item["mblog"]["raw_text"])
                    print(item["mblog"]["text"])
                else:
                    break;
        break;
    '''
'''
通过lbs信息查询可用位置信息
''' 
def getContainerInfoFromLbsInFo(lbsId, lon, lat):
    ext = '{"lbsType":"poi","lbsID":"%s"}'%lbsId
    ext = quote(ext)
    url = 'https://place.weibo.com/wandermap/paras?ext=%s&lng=%s&lat=%s'%(ext, lon, lat)
    headers = {
        'Host': 'place.weibo.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'Content-Type': 'application/x-www-form-urlencoded',
        'X-Requested-With': 'XMLHttpRequest',
        'Referer': 'https://place.weibo.com/',
        'Connection': 'keep-alive',
    }
    data = requests.get(url, timeout=10, headers=headers).json()
    return data

    
'''
通过container_id查询相关微博
''' 
def getWeibos(container_id):
    url = 'https://m.weibo.cn/api/container/getIndex?containerid=' + container_id
    headers = {
        'Host': 'm.weibo.cn',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
        'Accept': 'application/json, text/plain, */*',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'MWeibo-Pwa': '1',
        'X-Requested-With': 'XMLHttpRequest',
        'Referer': 'https://m.weibo.cn/p/cardlist?extparam=&containerid=' + container_id,
        'Connection': 'keep-alive',
    }
    data = requests.get(url, timeout=10, headers=headers).json()
    return data
    
if __name__ == "__main__":
    app.run(debug = True)


内容
隐藏