概要
今天(2023/3/17)将教大家怎么对中国五矿的采购信息(招标公告)进行爬取,难度为适中,内容包括:招标项目,招标时间,招标类型,招标公司等。

一、使用模块
import csv
import execjs
import requests
二、反爬技术
1.webpack
Webpack 是一个现代 JavaScript 应用程序的模块打包工具,它将各种资源(如 JavaScript、CSS、图片等)打包成优化后的文件,以提升加载速度和用户体验,但在爬虫角度上,它增加了抓取的复杂性
2.动态网页
动态网站通过JavaScript异步加载数据,需要查找数据接口,并且请求参数通常被加密参数保护。
3.数据加密
数据加密是为了保护数据的安全性和完整性,防止数据在传输过程中被恶意攻击者窃取或篡改。
三、分析过程
1.右键空白处,打开开发者工具,选择网络选项卡,过滤Fetch/XHR,刷新网页,点击采购信息

2.查找最后一条或响应数据量kb级的请求,成功定位到的数据接口。

3.查看请求负载,发现请求参数被加密

4.接下来,要定位加密的位置,但是按请求参数作为关键词搜索太范,(作者这里尝试过,发现有很多写好的url片段)于是使用路径作为关键词(也可以进行XHR断点)

5.在此处打上断点,刷新网页,点击采购信息,成功断着,并且t就是加密参数

6.接下来顺藤摸瓜,成功定位到加密位置,然后进行webpack处理

四、完整代码
import csv
import execjs
import requests
# 设置Cookies和Headers
cookies = {
'__jsluid_s': '4520412fb758708d03859275ce58a4c4',
'SUNWAY-ESCM-COOKIE': 'e4848fe6-0c7c-4af4-a950-24e1d54e69fd',
'JSESSIONID': '8087252179643C7719BF065980F400BB',
}
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,zh-TW;q=0.5',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'Origin': 'https://ec.minmetals.com.cn',
'Pragma': 'no-cache',
'Referer': 'https://ec.minmetals.com.cn/open/home/purchase-info',
'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/134.0.0.0 Safari/537.36 Edg/134.0.0.0',
'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
# 获取的密钥
def get_key():
response = requests.post('https://ec.minmetals.com.cn/open/homepage/public', cookies=cookies, headers=headers)
response.raise_for_status() # 检查请求是否成功
return response.text
# 设置请求多页的函数
def fetch_page(page_number):
key = get_key()
param = execjs.compile(open('./五矿.js', encoding='utf-8').read()).call('encParams', page_number, key)
json_data = {
'param': param,
}
response = requests.post(
'https://ec.minmetals.com.cn/open/homepage/zbs/by-lx-page',
cookies=cookies,
headers=headers,
json=json_data,
)
response.raise_for_status() # 检查请求是否成功
return response.json()
def save_data(writer, datas):
for data in datas:
writer.writerow(data)
def main():
# 请求多页,假设请求前5页
with open('五矿招标信息.csv', 'w', encoding='utf-8', newline='') as fp:
writer = csv.writer(fp)
writer.writerow(['招标名称', '招标类型1', '招标类型2', '招标部门', '招标时间']) # 写入表头
for page in range(1, 6): # 假设请求前5页
print(f"请求第 {page} 页")
try:
page_response = fetch_page(page)
datas = []
for item in page_response.get('list', []):
tender_name = item.get('mc')
tender_type1, tender_type2, tender_dep = item.get('condDes', '').split('/')
tender_time = item.get('rq')
datas.append([tender_name, tender_type1, tender_type2, tender_dep, tender_time])
save_data(writer, datas)
except Exception as e:
print(f"处理第 {page} 页时发生错误: {e}")
if __name__ == '__main__':
main()
小结
今天的内容比较简单,适合新手入门js逆向。

3271

被折叠的 条评论
为什么被折叠?



