from lxml import etree
import requests
# 供应商页
def szzfcg() -> dict:
res = requests.get("https://www.szzfcg.cn/default5.jsp")
root = etree.HTML(res.text)
tab = root.xpath("/html/body/table/tr[3]/td/table/tr/td[2]/table[2]/tr/td[2]")
d = dict()
for i in tab:
content = i.xpath("//div/a/text()")
url = i.xpath("//div/a/@href")
d = {str(content[i]).replace(" ", ""): str(url[i]) if not str(url[i]).startswith(
"/") else "https://szzfcg.cn" + str(url[i]) for
i in range(len(content))}
return d
# 市本级采购需求公示下载
def purchase() -> list:
purchase_url = szzfcg().get("市本级采购文件公示")
res = requests.get(purchase_url)
root = etree.HTML(res.text.encode('utf-8'))
url = root.xpath("//*[@id='pageContent']/div/form/div[2]/table//tr//a/@href")
text = root.xpath("//*[@id='pageContent']/div/form/div[2]/table//tr//a/text()")
# 下载招标文件
# https://www.szzfcg.cn/stock/stprFile.do?method=download&id=3214963
url = ["https://www.szzfcg.cn/stock/stprFile.do" + str(i) for i in url if str(i).startswith("?method")]
return url
# 市本级采购公告
def procurement(page: int):
"""
:param page: 市本级采购公告页数
:return:
"""
procurement_url = szzfcg().get("市本级采购公告")
for i in range(1, page + 1):
procurement_url = procurement_url[:-1] + str(i)
res = requests.get(procurement_url)
root = etree.HTML(res.text.encode('utf-8'))
url = root.xpath("//*[@id='pageContent']/div/form/div[2]/table//tr//a/@href")
# text = root.xpath("//*[@id='pageContent']/div/form/div[2]/table//tr//a/text()")
# https://www.szzfcg.cn/portal/documentView.do?method=view&id=
# /viewer.do?id=1003372206
url = ["https://www.szzfcg.cn/portal/documentView.do?method=view&id=" + str(i).split("=")[-1] for i in url if
str(i).startswith("/viewer")]
# 招标详情页数据
for i in url:
details_res = requests.get(i)
# print(details_res.text)
details_root = etree.HTML(details_res.text.encode('utf-8'))
# /html/body/table/tr/td/table[1]/tr/td
# /html/body/table/tbody/tr/td/table[1]/tbody/tr/td/ol
# todo (详情页里面 需要提取出来 预算,联系人,联系方式,开标时间。) 每个页面布局不一样 得写个好点的正则 估计得费点时间
# h3 = details_root.xpath("//h3")
# h3_content = details_root.xpath("//h3/text()")
# print(h3_content)
# h3_content= [str(i).encode('utf-8') for i in h3_content]
# print(h3_content)
fj_url = details_root.xpath("//@href")
# 找附件链接下载
for fj in fj_url:
if "fileDown" in fj:
print(fj)
try:
down_res = requests.get(str(fj))
with open(str(fj).split("=")[-1] + ".rar", "wb") as code:
code.write(down_res.content)
except Exception as e:
print(f"{fj},download err:{e}")
# http://zfcg.szggzy.com:8081/zcfg/list.html
# 广东省公共资源交易平台
def bf():
res = requests.get("https://ygp.gdzwfw.gov.cn/ggzy-portal/mhyy/config/cms/category/440000/11000?siteCode=440000")
print(res.cookies)
def zfcg():
cookies = {
'_horizon_uid': '6476aa19-0e7b-46a6-bb77-b3648128981c',
'_horizon_sid': '525c2334-2363-4eaf-beb4-255e399ff54b',
}
# todo X-Dgi-Req-Signature
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'Origin': 'https://ygp.gdzwfw.gov.cn',
'Referer': 'https://ygp.gdzwfw.gov.cn/ggzy-portal/',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36',
'X-Dgi-Req-App': 'ggzy-portal',
'X-Dgi-Req-Nonce': 'qI8r5Yvf6DWehzgw',
'X-Dgi-Req-Signature': '398715bd6417164ef22487d1d180478b0aac4616addcec4b3368bfce5f4f603e',
'X-Dgi-Req-Timestamp': '1676628454620',
'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
json_data = {
'type': 'trading-type',
'publishStartTime': '',
'publishEndTime': '',
'siteCode': '44',
'secondType': 'A',
'projectType': '',
'thirdType': '',
'dateType': '',
'total': 0,
'pageNo': 1,
'pageSize': 10,
'openConvert': False,
}
response = requests.post('https://ygp.gdzwfw.gov.cn/ggzy-portal/search/v1/items', cookies=cookies, headers=headers,
json=json_data)
print(response)
res = response.json().get("data")
if res:
for i in res.get("pageData"):
noticeSecondType = i.get("noticeSecondType")
projectType = i.get("projectType")
projectCode = i.get("projectCode")
siteCode = i.get("siteCode")
zfcg_details(noticeSecondType, projectType, projectCode, siteCode)
def zfcg_details(tradingType, projectCode, tradingProcess, siteCode):
cookies = {
'_horizon_uid': '6476aa19-0e7b-46a6-bb77-b3648128981c',
'_horizon_sid': '525c2334-2363-4eaf-beb4-255e399ff54b',
}
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Referer': 'https://ygp.gdzwfw.gov.cn/ggzy-portal/',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36',
'X-Dgi-Req-App': 'ggzy-portal',
'X-Dgi-Req-Nonce': 'NWoNs5jM4gcgQbwV',
'X-Dgi-Req-Signature': '9c3c9ae441e4cfd2bbddf1e440f05a19c977bfb4cec9a0f05c457fa07acf422b',
'X-Dgi-Req-Timestamp': '1676628713925',
'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
params = {
'tradingType': tradingType,
'projectCode': projectCode,
'tradingProcess': tradingProcess,
'siteCode': siteCode,
}
response = requests.get(
'https://ygp.gdzwfw.gov.cn/ggzy-portal/center/apis/trading-notice/detail',
params=params,
cookies=cookies,
headers=headers,
)
print(response)
if __name__ == '__main__':
# procurement(2)
# zfcg()
bf()
广东省公共资源交易平台 逆向 X-Dgi-Req-Signature
function Dc(e) {
let t;
switch (e) {
case "base":
t = "/ggzy-portal/base/";
break;
case "search":
t = "/ggzy-portal/search/";
break;
case "yhzx":
t = "/ggzy-yhzx/";
break;
case "stat":
t = "/ggzy-portal/center/apis/stat/";
break;
case "mhyy":
t = "/ggzy-portal/mhyy/config/";
break;
default:
t = "/ggzy-portal/center/apis/";
break
}
const n = WY.create({
baseURL: t,
...bq
});
function u(o) {
si.inc();
const r = Nr()
, {params: i, url: s} = o
# a 时间戳 X-Dgi-Req-Timestamp: 1676884484177
, a = Date.now()
# l 随机字符串 X-Dgi-Req-Nonce: "qBbXuOeeHdLZDJVH"
, l = Aq(16)
# c是固定的 "k8tUyS$m"
, c = lr([8, 28, 20, 42, 21, 53, 65, 6])
, f = {
[lr([56, 62, 52, 11, 23, 62, 39, 18, 16, 62, 54, 25, 25])]: lr([11, 11, 0, 21, 62, 25, 24, 19, 20, 15, 7]),
[lr([56, 62, 52, 11, 23, 62, 39, 18, 16, 62, 60, 24, 5, 2, 18])]: l,
[lr([56, 62, 52, 11, 23, 62, 39, 18, 16, 62, 40, 23, 6, 18, 14, 20, 15, 6, 25])]: a
};
if (o.method.toLowerCase() === "get") {
(i == null ? void 0 : i.siteCode) === void 0 && !s.includes("?siteCode=") && (i ? o.params.siteCode = r.currentSite : o.params = {
siteCode: r.currentSite
});
const d = Ig({
p: i,
t: a,
n: l,
k: c
});
f[[lr([56, 62, 52, 11, 23, 62, 39, 18, 16, 62, 53, 23, 11, 5, 15, 20, 22, 19, 18])]] = d
} else {
const d = Ig({
p: ey.stringify(o.data, {
allowDots: !0
}),
t: a,
n: l,
k: c
});
f[[lr([56, 62, 52, 11, 23, 62, 39, 18, 16, 62, 53, 23, 11, 5, 15, 20, 22, 19, 18])]] = d,
e === "mhyy" && (o.data ? o.data.noSiteCode ? delete o.data.noSiteCode : o.data.siteCode === void 0 && (o.data.siteCode = r.currentSite) : o.data = {
siteCode: r.currentSite
})
}
return o.headers = {
...f,
...o.headers
},
o
}
return n.interceptors.request.use(u, Dq),
n.interceptors.response.use(wq, xq),
n
}
ig 代码:
( t: a,n: l,k: c)
function Ig(e={}) {
const {p: t, t: n, n: u, k: o} = e
, r = Bq(t);
return Cq(u + o + decodeURIComponent(r) + n)
}
Bq 代码:
function Bq(e) {
let t = "";
return typeof e == "object" ? t = Object.keys(e).map(n=>`${n}=${e[n]}`).sort().join("&") : typeof e == "string" && (t = e.split("&").sort().join("&")),
t
}
Cq 代码: 参数 B: 随机字符串l+固定字符串c +decodeURIComponent(r) +时间戳 a
function(B, x) {
return new C.init(x).finalize(B)
C.init(x).finalize(B)代码: 参数:B: "Gd8t6HVFaAUfa51zk8tUyS$m1676886449404" x: undefined
finalize: function(C) {
C && this._append(C);
var B = this._doFinalize();
return B
},
._append(C)代码:
_append: function(C) {
typeof C == "string" && (C = m.parse(C)),
this._data.concat(C),
this._nDataBytes += C.sigBytes
},
_append中的 m.parse(C)代码:核心代码将l+c+a组成的字符串 拆解生成 X-Dgi-Req-Signature---> init 生成长度10的 words数组
parse: function(C) {
for (var B = C.length, x = [], b = 0; b < B; b++)
x[b >>> 2] |= (C.charCodeAt(b) & 255) << 24 - b % 4 * 8;
return new f.init(x,B)
}
parse中的 f.init(x,B)代码(加工生成长度10的 words数组 ):
init: function(C, B) {
C = this.words = C || [],
B != o ? this.sigBytes = B : this.sigBytes = C.length * 4
},
_append中的concat(C):
concat: function(C) {
var B = this.words
, x = C.words
, b = this.sigBytes
, _ = C.sigBytes;
if (this.clamp(),
b % 4)
for (var D = 0; D < _; D++) {
var I = x[D >>> 2] >>> 24 - D % 4 * 8 & 255;
B[b + D >>> 2] |= I << 24 - (b + D) % 4 * 8
}
else
for (var O = 0; O < _; O += 4)
B[b + O >>> 2] = x[O >>> 2];
return this.sigBytes += _,
this
},
_doFinalize 代码:处理生成的words数组 转为长度为8的数组
_doFinalize: function() {
var h = this._data
, p = h.words
, m = this._nDataBytes * 8
, v = h.sigBytes * 8;
return p[v >>> 5] |= 128 << 24 - v % 32,
p[(v + 64 >>> 9 << 4) + 14] = u.floor(m / 4294967296),
p[(v + 64 >>> 9 << 4) + 15] = m,
h.sigBytes = p.length * 4,
this._process(),
this._hash
},
_doFinalize中的process代码:
_process: function(C) {
var B, x = this._data, b = x.words, _ = x.sigBytes, D = this.blockSize, I = D * 4, O = _ / I;
C ? O = u.ceil(O) : O = u.max((O | 0) - this._minBufferSize, 0);
var P = O * D
, j = u.min(P * 4, _);
if (P) {
for (var H = 0; H < P; H += D)
this._doProcessBlock(b, H);
B = b.splice(0, P),
x.sigBytes -= j
}
return new f.init(B,j)
},
_doFinalize中的process中的_doProcessBlock代码():
_doProcessBlock: function(h, p) {
for (var m = this._hash.words, v = m[0], g = m[1], C = m[2], B = m[3], x = m[4], b = m[5], _ = m[6], D = m[7], I = 0; I < 64; I++) {
if (I < 16)
f[I] = h[p + I] | 0;
else {
var O = f[I - 15]
, P = (O << 25 | O >>> 7) ^ (O << 14 | O >>> 18) ^ O >>> 3
, j = f[I - 2]
, H = (j << 15 | j >>> 17) ^ (j << 13 | j >>> 19) ^ j >>> 10;
f[I] = P + f[I - 7] + H + f[I - 16]
}
var Y = x & b ^ ~x & _
, L = v & g ^ v & C ^ g & C
, M = (v << 30 | v >>> 2) ^ (v << 19 | v >>> 13) ^ (v << 10 | v >>> 22)
, U = (x << 26 | x >>> 6) ^ (x << 21 | x >>> 11) ^ (x << 7 | x >>> 25)
, R = D + U + Y + c[I] + f[I]
, ee = M + L;
D = _,
_ = b,
b = x,
x = B + R | 0,
B = C,
C = g,
g = v,
v = R + ee | 0
}
m[0] = m[0] + v | 0,
m[1] = m[1] + g | 0,
m[2] = m[2] + C | 0,
m[3] = m[3] + B | 0,
m[4] = m[4] + x | 0,
m[5] = m[5] + b | 0,
m[6] = m[6] + _ | 0,
m[7] = m[7] + D | 0
},
Aq: 生成 X-Dgi-Req-Nonce的
function Aq(e) {
return [...Array(e)].map(()=>ky[yq(0, 61)]).join("")
}
生成过程:
代码:
import random
import string
import time
import requests
if __name__ == '__main__':
import execjs
# "k8tUyS$m"
ctx = execjs.compile(
"""
var Br = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {};
var xy = {
exports: {}
};
var rf = {
exports: {}
}, Pg;
function vq() {
return Pg || (Pg = 1,
function(e, t) {
(function(n, u) {
e.exports = u()
}
)(Br, function() {
var n = n || function(u, o) {
var r;
if (typeof window < "u" && window.crypto && (r = window.crypto),
typeof self < "u" && self.crypto && (r = self.crypto),
typeof globalThis < "u" && globalThis.crypto && (r = globalThis.crypto),
!r && typeof window < "u" && window.msCrypto && (r = window.msCrypto),
!r && typeof Br < "u" && Br.crypto && (r = Br.crypto),
!r && typeof Eq == "function")
try {
r = YC
} catch(err) {}
var i = function() {
if (r) {
if (typeof r.getRandomValues == "function")
try {
return r.getRandomValues(new Uint32Array(1))[0]
} catch(err) {}
if (typeof r.randomBytes == "function")
try {
return r.randomBytes(4).readInt32LE()
} catch(err) {}
}
throw new Error("Native crypto module could not be used to get secure random number.")
}
, s = Object.create || function() {
function C() {}
return function(B) {
var x;
return C.prototype = B,
x = new C,
C.prototype = null,
x
}
}()
, a = {}
, l = a.lib = {}
, c = l.Base = function() {
return {
extend: function(C) {
var B = s(this);
return C && B.mixIn(C),
(!B.hasOwnProperty("init") || this.init === B.init) && (B.init = function() {
B.$super.init.apply(this, arguments)
}
),
B.init.prototype = B,
B.$super = this,
B
},
create: function() {
var C = this.extend();
return C.init.apply(C, arguments),
C
},
init: function() {},
mixIn: function(C) {
for (var B in C)
C.hasOwnProperty(B) && (this[B] = C[B]);
C.hasOwnProperty("toString") && (this.toString = C.toString)
},
clone: function() {
return this.init.prototype.extend(this)
}
}
}()
, f = l.WordArray = c.extend({
init: function(C, B) {
C = this.words = C || [],
B != o ? this.sigBytes = B : this.sigBytes = C.length * 4
},
toString: function(C) {
return (C || h).stringify(this)
},
concat: function(C) {
var B = this.words
, x = C.words
, b = this.sigBytes
, _ = C.sigBytes;
if (this.clamp(),
b % 4)
for (var D = 0; D < _; D++) {
var I = x[D >>> 2] >>> 24 - D % 4 * 8 & 255;
B[b + D >>> 2] |= I << 24 - (b + D) % 4 * 8
}
else
for (var O = 0; O < _; O += 4)
B[b + O >>> 2] = x[O >>> 2];
return this.sigBytes += _,
this
},
clamp: function() {
var C = this.words
, B = this.sigBytes;
C[B >>> 2] &= 4294967295 << 32 - B % 4 * 8,
C.length = u.ceil(B / 4)
},
clone: function() {
var C = c.clone.call(this);
return C.words = this.words.slice(0),
C
},
random: function(C) {
for (var B = [], x = 0; x < C; x += 4)
B.push(i());
return new f.init(B,C)
}
})
, d = a.enc = {}
, h = d.Hex = {
stringify: function(C) {
for (var B = C.words, x = C.sigBytes, b = [], _ = 0; _ < x; _++) {
var D = B[_ >>> 2] >>> 24 - _ % 4 * 8 & 255;
b.push((D >>> 4).toString(16)),
b.push((D & 15).toString(16))
}
return b.join("")
},
parse: function(C) {
for (var B = C.length, x = [], b = 0; b < B; b += 2)
x[b >>> 3] |= parseInt(C.substr(b, 2), 16) << 24 - b % 8 * 4;
return new f.init(x,B / 2)
}
}
, p = d.Latin1 = {
stringify: function(C) {
for (var B = C.words, x = C.sigBytes, b = [], _ = 0; _ < x; _++) {
var D = B[_ >>> 2] >>> 24 - _ % 4 * 8 & 255;
b.push(String.fromCharCode(D))
}
return b.join("")
},
parse: function(C) {
for (var B = C.length, x = [], b = 0; b < B; b++)
x[b >>> 2] |= (C.charCodeAt(b) & 255) << 24 - b % 4 * 8;
return new f.init(x,B)
}
}
, m = d.Utf8 = {
stringify: function(C) {
try {
return decodeURIComponent(escape(p.stringify(C)))
} catch(err) {
throw new Error("Malformed UTF-8 data")
}
},
parse: function(C) {
return p.parse(unescape(encodeURIComponent(C)))
}
}
, v = l.BufferedBlockAlgorithm = c.extend({
reset: function() {
this._data = new f.init,
this._nDataBytes = 0
},
_append: function(C) {
typeof C == "string" && (C = m.parse(C)),
this._data.concat(C),
this._nDataBytes += C.sigBytes
},
_process: function(C) {
var B, x = this._data, b = x.words, _ = x.sigBytes, D = this.blockSize, I = D * 4, O = _ / I;
C ? O = u.ceil(O) : O = u.max((O | 0) - this._minBufferSize, 0);
var P = O * D
, j = u.min(P * 4, _);
if (P) {
for (var H = 0; H < P; H += D)
this._doProcessBlock(b, H);
B = b.splice(0, P),
x.sigBytes -= j
}
return new f.init(B,j)
},
clone: function() {
var C = c.clone.call(this);
return C._data = this._data.clone(),
C
},
_minBufferSize: 0
});
l.Hasher = v.extend({
cfg: c.extend(),
init: function(C) {
this.cfg = this.cfg.extend(C),
this.reset()
},
reset: function() {
v.reset.call(this),
this._doReset()
},
update: function(C) {
return this._append(C),
this._process(),
this
},
finalize: function(C) {
C && this._append(C);
var B = this._doFinalize();
return B
},
blockSize: 16,
_createHelper: function(C) {
return function(B, x) {
return new C.init(x).finalize(B)
}
},
_createHmacHelper: function(C) {
return function(B, x) {
return new g.HMAC.init(C,x).finalize(B)
}
}
});
var g = a.algo = {};
return a
}(Math);
return n
})
}(rf)),
rf.exports
}
// 匿名函数
(function(e, t) {
(function(n, u) {
e.exports = u(vq())
}
)(Br, function(n) {
return function(u) {
var o = n
, r = o.lib
, i = r.WordArray
, s = r.Hasher
, a = o.algo
, l = []
, c = [];
(function() {
function h(g) {
for (var C = u.sqrt(g), B = 2; B <= C; B++)
if (!(g % B))
return !1;
return !0
}
function p(g) {
return (g - (g | 0)) * 4294967296 | 0
}
for (var m = 2, v = 0; v < 64; )
h(m) && (v < 8 && (l[v] = p(u.pow(m, 1 / 2))),
c[v] = p(u.pow(m, 1 / 3)),
v++),
m++
}
)();
var f = []
, d = a.SHA256 = s.extend({
_doReset: function() {
this._hash = new i.init(l.slice(0))
},
_doProcessBlock: function(h, p) {
for (var m = this._hash.words, v = m[0], g = m[1], C = m[2], B = m[3], x = m[4], b = m[5], _ = m[6], D = m[7], I = 0; I < 64; I++) {
if (I < 16)
f[I] = h[p + I] | 0;
else {
var O = f[I - 15]
, P = (O << 25 | O >>> 7) ^ (O << 14 | O >>> 18) ^ O >>> 3
, j = f[I - 2]
, H = (j << 15 | j >>> 17) ^ (j << 13 | j >>> 19) ^ j >>> 10;
f[I] = P + f[I - 7] + H + f[I - 16]
}
var Y = x & b ^ ~x & _
, L = v & g ^ v & C ^ g & C
, M = (v << 30 | v >>> 2) ^ (v << 19 | v >>> 13) ^ (v << 10 | v >>> 22)
, U = (x << 26 | x >>> 6) ^ (x << 21 | x >>> 11) ^ (x << 7 | x >>> 25)
, R = D + U + Y + c[I] + f[I]
, ee = M + L;
D = _,
_ = b,
b = x,
x = B + R | 0,
B = C,
C = g,
g = v,
v = R + ee | 0
}
m[0] = m[0] + v | 0,
m[1] = m[1] + g | 0,
m[2] = m[2] + C | 0,
m[3] = m[3] + B | 0,
m[4] = m[4] + x | 0,
m[5] = m[5] + b | 0,
m[6] = m[6] + _ | 0,
m[7] = m[7] + D | 0
},
_doFinalize: function() {
var h = this._data
, p = h.words
, m = this._nDataBytes * 8
, v = h.sigBytes * 8;
return p[v >>> 5] |= 128 << 24 - v % 32,
p[(v + 64 >>> 9 << 4) + 14] = u.floor(m / 4294967296),
p[(v + 64 >>> 9 << 4) + 15] = m,
h.sigBytes = p.length * 4,
this._process(),
this._hash
},
clone: function() {
var h = s.clone.call(this);
return h._hash = this._hash.clone(),
h
}
});
o.SHA256 = s._createHelper(d),
o.HmacSHA256 = s._createHmacHelper(d)
}(Math),
n.SHA256
})
}
)(xy);
var Cq = xy.exports;
// var k="k8tUyS$m",n="XgsNo3npVzcW9DOU",p="",t=1676974388321, r = Bq(t);
// const {p: t, t: n, n: u, k: o} = e
// , r = Bq(t);
// return Cq(u + o + decodeURIComponent(r) + n)
function Bq(e) {
let t = "";
return typeof e == "object" ? t = Object.keys(e).map(n=>`${n}=${e[n]}`).sort().join("&") : typeof e == "string" && (t = e.split("&").sort().join("&")),
t
}
function Ig(params) {
// k8tUyS$m
//var r = Bq(t);
//var C = Cq(a+c+decodeURIComponent(r)+l)
var C = Cq(params)
for (var B = C.words, x = C.sigBytes, b = [], _ = 0; _ < x; _++) {
var D = B[_ >>> 2] >>> 24 - _ % 4 * 8 & 255;
b.push((D >>> 4).toString(16)),
b.push((D & 15).toString(16))
}
return b.join("")
}
"""
)
def zfcg(key, siteCode, secondType, pageNo, pageSize):
"""
:param key: 固定的c
:param siteCode: siteCode 44是广东省 440300是深圳市
:param secondType: # 工程建设是A 土地矿业是B 国有产权是C
:param pageNo:
:param pageSize:
:return:
"""
cookies = {
'_horizon_uid': '6476aa19-0e7b-46a6-bb77-b3648128981c',
'_horizon_sid': '525c2334-2363-4eaf-beb4-255e399ff54b',
}
# todo X-Dgi-Req-Signature
json_data = {
'type': 'trading-type',
'publishStartTime': '',
'publishEndTime': '',
'siteCode': siteCode,
'secondType': secondType,
'projectType': '',
'thirdType': '',
'dateType': '',
'total': 0,
#
'pageNo': int(pageNo),
'pageSize': int(pageSize),
'openConvert': False,
}
random_s = random.sample(string.ascii_letters + string.digits, 16)
Nonce = ''.join(random_s)
Timestamp = str(int(time.time() * 1000))
# 没请求参数的话 一般不加这个东西 (基本就是请求参数) 这个生成签名需要
t = "dateType=&openConvert=false&pageNo=%s&pageSize=%s&projectType=&publishEndTime=&publishStartTime=&secondType=%s&siteCode=%s&thirdType=&total=0&type=trading-type" % (
pageNo, pageSize, secondType, siteCode)
Signature = ctx.call('Ig', Nonce + key + t + Timestamp)
print('sign--------------------------------------------->', Signature)
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'Origin': 'https://ygp.gdzwfw.gov.cn',
'Referer': 'https://ygp.gdzwfw.gov.cn/ggzy-portal/',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36',
'X-Dgi-Req-App': 'ggzy-portal',
'X-Dgi-Req-Nonce': Nonce,
'X-Dgi-Req-Signature': Signature,
'X-Dgi-Req-Timestamp': Timestamp,
'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
response = requests.post('https://ygp.gdzwfw.gov.cn/ggzy-portal/search/v1/items', cookies=cookies,
headers=headers,
json=json_data)
print(response.json())
res = response.json().get("data")
if res:
for i in res.get("pageData"):
noticeSecondType = i.get("noticeSecondType")
projectType = i.get("projectType")
projectCode = i.get("projectCode")
siteCode = i.get("siteCode")
details(noticeSecondType, projectCode, projectType, siteCode)
# 详情
def details(tradingType,projectCode,tradingProcess,siteCode):
cookies = {
'_horizon_uid': 'ac35adbe-438b-424e-b85e-b80416fbabe0',
'_horizon_sid': 'a7a555cb-6c3c-492c-b392-e373598df94a',
}
random_s = random.sample(string.ascii_letters + string.digits, 16)
Nonce = ''.join(random_s)
Timestamp = str(int(time.time() * 1000))
params = {
'tradingType': tradingType,
'projectCode': projectCode,
'tradingProcess': tradingProcess,
'siteCode': siteCode,
}
t="projectCode=%s&siteCode=%s&tradingProcess=%s&tradingType=%s" %(projectCode,siteCode,tradingProcess,tradingType)
Signature = ctx.call('Ig', Nonce + key + t + Timestamp)
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Referer': 'https://ygp.gdzwfw.gov.cn/',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36',
'X-Dgi-Req-App': 'ggzy-portal',
'X-Dgi-Req-Nonce': Nonce,
'X-Dgi-Req-Signature': Signature,
'X-Dgi-Req-Timestamp': Timestamp,
'sec-ch-ua': '"Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
}
response = requests.get(
'https://ygp.gdzwfw.gov.cn/ggzy-portal/center/apis/trading-notice/detail',
params=params,
cookies=cookies,
headers=headers,
)
print(response.json())
key = 'k8tUyS$m'
siteCode = '44'
secondType = 'A'
pageNo = '1'
pageSize = '20'
zfcg(key=key, siteCode=siteCode, secondType=secondType, pageNo=pageNo, pageSize=pageSize)
# 工程建设:A01 项目进场 A02 招标公告 A04 开标公告 A05 评标报告 A06 结果公告 A07 资格预审 A08 中标候选人公示 A09 招标异常情况报告 A10 履约信息
# 土地矿业 :A01 出让公告 A02 出让结果公示 TY-B-07 挂牌文件
# 国有产权 :C01 挂牌披露 C02 交易结果 TY-C-07 产权挂牌/拍卖过程信息 TY-C-11 结果公告
# details(tradingType='A',projectCode='X440200083200017i172',tradingProcess='A01',siteCode='440200')
结束: