python爬取百度天气接口【实战记录】


前言

利用python 模拟浏览器获取百度的天气接口

提示:以下是本篇文章正文内容,下面案例可供参考

一、确定爬取的对象

在这里插入图片描述
http://weathernew.pae.baidu.com/weathernew/pc?query=%E6%9D%AD%E5%B7%9E%E5%A4%A9%E6%B0%94&srcid=4982&city_name=%E6%9D%AD%E5%B7%9E&province_name=%E6%B5%99%E6%B1%9F

二、开始分析

第一步当然是通过浏览器打开http://weathernew.pae.baidu.com/weathernew/pc?query=%E6%9D%AD%E5%B7%9E%E5%A4%A9%E6%B0%94&srcid=4982&city_name=%E6%9D%AD%E5%B7%9E&province_name=%E6%B5%99%E6%B1%9F这个网站,然后按下F12,点击network,查看前端向后台发送的是什么请求

在这里插入图片描述

页面第一个发送的请求,就是发送查询天气的接口,
在这里插入图片描述
仔细看了哈request的请求头并没有token,sign之类的参数,似乎好像难度不大,在看看响应头信息
在这里插入图片描述
响应头信息,返回了一个html页面代码,怎么获取天气信息呢?等等,页面中的脚本中有一个
window.tplData 语句,是不是,这个信息存放在window对象内,在控制台中输出一下,试一下:

在这里插入图片描述
果然是这个样子,向这个地址发送请求,它的响应信息在页面的window对象里面,把值取出来就搞定了。但是,怎么从页面中从window 对象中取值呢?
百度了一下一下,python提供了两个比较常用的库execjs、js2py 两个库可以执行javascript 语句,我这里就用execjs这个库

安装execjs

pip install execjs

等了一会安装好了,开始写python代码

from urllib.parse import urlencode
import requests
url = 'http://weathernew.pae.baidu.com/weathernew/pc'
city = '杭州'
province = '浙江省'
query = '{%s}天气'%{city}
srcid = 4982
params = {
    'query':query,
    'srcid':srcid,
    'city_name':city,
    'province_name':province
}
print(params)
headers = {
    'cookie': 'BAIDUID=0DE9E99FCAA93BB44E1F5A3FB9551C5E:FG=1; PSTM=1617506980; BIDUPSID=5AABE7C0A1B4B37C7CDCA3EBE496C373; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; H_PS_PSSID=; delPer=0; PSINO=1; BA_HECTOR=2104858521250181pq1g6ksm20r; Hm_lvt_3535ee208b02ecdf4b2576fd444e8473=1617588962; Hm_lpvt_3535ee208b02ecdf4b2576fd444e8473=1617588973',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
    'Referer': 'http://weathernew.pae.baidu.com/',
}
response = requests.get(url,headers=headers,params=params)
print(response)

到这里,获取了页面的源代码了,但是怎么获取页面的window对象呢?对,借鉴哈前人的经验
https://www.cnblogs.com/shizhengwen/p/14092614.html
还真有门路,使用node 里面的jsdom ,似乎我本地也有node 环境
全局安装

npm install jsdom -g

执行下面的这段代码

tag = """const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
window = dom.window;
document = window.document;
XMLHttpRequest = window.XMLHttpRequest; """ 
js = execjs.compile(tag)

在这里插入图片描述

报错了,说找不到jsdom这个模块,咱查看一下刚才把jsom 全局安装到哪里去了

npm root -g 

在这里插入图片描述

有解决办法,把刚才的代码改良一下

tag = """const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
window = dom.window;
document = window.document;
XMLHttpRequest = window.XMLHttpRequest; """
js = execjs.compile(tag,cwd=r'D:\node-v14.15.1-win-x64\node_modules')

在这里插入图片描述

这似乎还是不太顺利,不过没事继续找解决方案

使用python的execjs执行js,会有这个错误:UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 41: illegal multibyte sequence这个问题原因是文件编码问题,具体可以 Google 一下,这里直接解决方法是通过修改 subprocess.py 中的 Popen 类的构造方法 __init__ 中 encoding 参数的默认值为 utf-8。
原来如此,我来试试:
在这里插入图片描述
修改后
在这里插入图片描述
运行试试
在这里插入图片描述
Greate 数据获取成功
全部源代码:

from urllib.parse import urlencode

import execjs
import requests
from bs4 import BeautifulSoup
url = 'http://weathernew.pae.baidu.com/weathernew/pc'
city = '杭州'
province = '浙江省'
query = '{%s}天气'%{city}
srcid = 4982
params = {
    'query':query,
    'srcid':srcid,
    'city_name':city,
    'province_name':province
}
headers = {
    'cookie': 'BAIDUID=0DE9E99FCAA93BB44E1F5A3FB9551C5E:FG=1; PSTM=1617506980; BIDUPSID=5AABE7C0A1B4B37C7CDCA3EBE496C373; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; H_PS_PSSID=; delPer=0; PSINO=1; BA_HECTOR=2104858521250181pq1g6ksm20r; Hm_lvt_3535ee208b02ecdf4b2576fd444e8473=1617588962; Hm_lpvt_3535ee208b02ecdf4b2576fd444e8473=1617588973',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
    'Referer': 'http://weathernew.pae.baidu.com/',
}
response = requests.get(url,headers=headers,params=params)
soup = BeautifulSoup(response.text, features="lxml")
tag = soup.find_all("script")[0].decode_contents()
tag = """const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
window = dom.window;
document = window.document;
XMLHttpRequest = window.XMLHttpRequest; """ + tag
js = execjs.compile(tag, cwd=r'D:\node-v14.15.1-win-x64\node_modules')

tplData = js.eval("window.tplData")
print(tplData)
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值