102302141_易敏亮第二次数据采集作业
作业①:
要求:在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库。
简介:
通过F12网络功能查找关键元素“晴转多云”,快速定位数据所在,发现在' https://www.weather.com.cn/weather/101010100.shtml '异步加载,观察发现不同城市数据映射url的字符串相同。
通过查找发现' https://j.i8tq.com/weather2020/search/city.js '中存储了城市->字符串映射关系,且为标准字典,可根据其查询。
心得:
深刻体会到逆向思维在数据采集中的重要性——从页面显示的"晴转多云"等关键词出发,通过浏览器开发者工具反向追踪数据源,成功定位到隐藏的异步接口和城市编码映射文件。这不仅揭示了网页表面结构与真实数据源的差异,更让我认识到动态网站的数据往往通过API异步加载,直接分析网络请求比解析静态HTML更能高效获取结构化数据。


def get_weather_data(city_id):
url = f"https://www.weather.com.cn/weather/{city_id}.shtml"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36"
}
response = requests.get(url, headers=headers)
response.encoding = 'utf-8' # 防止乱码
text = response.text
info = []
soup = BeautifulSoup(text, 'lxml')
tags = soup.select("ul[class='t clearfix'] li")
for tag in tags:
day = tag.find("h1").get_text().strip()
weather = tag.find("p", class_="wea").get_text().strip()
tem = tag.find("p", class_="tem").get_text().strip()
info.append((day, weather, tem))
return info
作业②
要求:用requests和json解析方法定向爬取股票(东方财富网:https://www.eastmoney.com/)相关信息,并存储在数据库中
简介:
东方财富网站传输数据在接口' https://push2.eastmoney.com/api/qt/clist/get?np=1&fltt=1&invt=2&cb=jQuery3710324951759523461_1761760021174&fs=板块参数&fields=板块参数&fid=f3&pn=翻页数&pz=每页数量&po=1&dect=1&ut=fa5fd1943c7b386f172d6893dbfba10b&wbp2u=|0|0|0|web&_=时间戳 ',加载数据使用jsonp文件,简短裁剪可以化作json文件解析。
心得:
通过带时间戳的动态回调函数包装JSON数据,只需识别并去除jQuery回调函数(前缀和)后缀,即可将JSONP转换为标准JSON格式进行解析。这让我认识到很多网站采用JSONP实现跨域数据交互,核心在于理解其回调机制并做相应清洗处理,相比解析HTML页面能更高效地获取结构化数据。
中间发生过爬取太多断开remote,通过修改header中代理头解决,同时也告诫爬虫编写过程中,合适的爬取数量和本地加载是很有必要的
# jsonp转json
def parse_jsonp_simple(jsonp_str):
start = jsonp_str.find('(')
end = jsonp_str.rfind(')')
if start != -1 and end != -1:
json_str = jsonp_str[start+1:end]
return json.loads(json_str)
else:
raise ValueError("无效的JSONP格式")
# 解析后写入
with open("eastmoney.csv", 'w', encoding='utf-8') as f:
f.write("序号,股票代码,股票名称,最新价,涨跌幅(%),涨跌额,成交量(万手),成交额(亿元),振幅(%),最高价,最低价,今开,昨收\n")
for i in range(1,100):
url = get_url(i)
data = get_data(url)
news_list = data['data']['diff']
with open("eastmoney.csv", 'a', encoding='utf-8') as f:
for j,stock in enumerate(news_list, 1):
f.write(
f"{(i-1)*20+j},"
f"{stock.get('f12', '')}," # 股票代码
f"{stock.get('f14', '')},"# 股票名称
f"{stock.get('f2', 0)/100:.2f}," # 最新价
f"{stock.get('f3', 0)/100:.2f}," # 涨跌幅(%)
f"{stock.get('f4', 0)/100:.2f}," # 涨跌额
f"{stock.get('f5', 0)/10000:.2f}," # 成交量转万手
f"{stock.get('f6', 0)/100000000:.2f}," # 成交额转亿元
f"{stock.get('f7', 0)/100:.2f}," # 振幅(%)
f"{stock.get('f15', 0)/100:.2f}," # 最高价
f"{stock.get('f16', 0)/100:.2f}," # 最低价
f"{stock.get('f17', 0)/100:.2f}," # 今开
f"{stock.get('f18', 0)/100:.2f}\n") # 昨收


作业③:
要求:爬取中国大学2021主榜所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。
简介:
所需数据在' https://www.shanghairanking.cn/_nuxt/static/1761118404/rankings/bcur/2021/payload.js '接口中,score数据很好找,但是province和Category数据用1-2字节字母替代。观察js代码发现function代码输入(开头)与结尾一一对应。
心得:
该网站将完整数据预渲染在payload.js文件中,虽然省份和院校类型字段采用1-2字节编码替代,但通过仔细分析JavaScript函数映射关系成功破解了编码规则。这让我认识到前端框架常采用静态化优化,关键数据往往隐藏在看似复杂的文件结构中,需要耐心分析JS代码逻辑才能完整解码数据含义,相比动态接口反而提供了更稳定的数据源。
# 构建映射字典,其中a,b从javascript脚本中复制
def get_dict():
dict = {}
a=("a, b, c, d, e, f, g......}
b=('"", false, null, 0, "理工", "综合".....)
a1 = a.split(', ')
b1 = b.split(', ')
for i in range(len(a1)):
a1[i] = a1[i].strip().strip('"').strip("'")
b1[i] = b1[i].strip().strip('"').strip("'")
dict[a1[i]] = b1[i]
return dict
(
)

浙公网安备 33010602011771号