使用公众号自带的接口去抓取想要的信息,首先要在自己的公众号中对文章或者公众号进行查找,在数据包中解析出想要的信息,过程中最重要的几个难点:
- cookies:标识别登录信息
- token:个人标识
- fakeid:标识公众号
1. 调用接口查找文章
进入主页 -> 素材管理 -> 新建图文 -> 超链接 -> 查找文章
I. 素材管理
II. 新建图文
III. 超链接
IV. 查找文章
2. 抓取所有相关公众号信息
我们输入关键字并点击搜索后,右侧会出现相应的数据包,这里比较好找,选中
xhr
后只会出现唯一的数据包
I. 查看访问参数
选中它选择
headers
栏滑到最下方可以看到一系列的请求参数,比较重要的参数无非token
、query
(搜索关键字)、begin
(开始的数值)、count
(每页显示的数值),在headers
中还能够看到数据的真实url
,之后会向他发起请求
II. 查看数据包内容
在这里可以看到数据包内返回的所有内容,一般都是
json
格式,也可以查看一下是否与页面上看的的内容相对应,这里在返回数据的list
列表中可以看到每个公众号的信息,包括fakeid
(之后访问公众号文章会用到),公众号名称、公众号号码和总搜索量
III. 流程分析
我们通过模拟登陆获取到
cookie
后,访问主页获取到url
上的token
标识,通过向抓取到的数据包上面的真实url
发送请求以及数据来获取相应信息,在返回的信息中,通过解析total
判断总数量,改变begin
的数值来执行翻页,最后将信息写入文件
class Public(metaclass=SingletonType):
def __init__(self, search_key, token, cookie):
self.search_key = search_key
self.url = 'https://mp.weixin.qq.com/cgi-bin/searchbiz?'
self.headers = {
'cookie': cookie,
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/74.0.3729.169 Safari/537.36'
}
self.data = {
'action': 'search_biz',
'token': token,
'lang': 'zh_CN',
'f': 'json',
'ajax': '1',
'random': '0.012103784566473319',
'query': self.search_key,
'count': '5'
}
def get_total(self):
self.data['begin'] = 0
content = requests.get(self.url, headers=self.headers, params=self.data).json()
total = content['total']
if total % 5:
return int(total / 5) + 1
else:
return int(total / 5)
def parse_public(self, num):
self.data['begin'] = num
content = requests.get(self.url, headers=self.headers, params=self.data).json()
return content
def get_data(self):
for num in range(0, self.get_total() + 1, 5):
for data in self.parse_public(num)['list']:
yield {
"name": data['nickname'],
"id": data['fakeid'],
'number': data['alias']
}
time.sleep(random.randint(1, 3))
def write_data(result, filename):
for data in result:
print(data)
with open(filename, 'a', encoding='utf-8') as f:
f.write(json.dumps(data, ensure_ascii=False) + '\n')
3. 抓取公众号下的文章
在上一步的操作后选定相应的公众号并执行抓包,可以看到新的数据包,包含其下的所有文章列表
I 抓包
II. 查看请求参数
很明显,这里就用到了之前我们所获取到的
fakeid
信息,其他的都和之前类似,query
同样是搜索关键字,指定query
后会返回相关搜索项,未指定则默认为空,返回默认的
III. 查看数据内容
IV. 流程分析
通过模拟登陆后获取到
cookie
和token
,fakeid
可以自行获取,参考上一部分获取公众号信息的内容,然后向数据包的真实url
发送请求,对返回的数据做解析,通过app_msg_cnt
获取总量,更改begin
值执行翻页,获取文章标题、创建时间(时间戳需要转为时间格式)、文章简述、文章链接等信息,最后执行写入文件操作
class Articls(metaclass=SingletonType):
def __init__(self, token, fakeid, cookie, search_key=""):
self.search_key = search_key
self.url = 'https://mp.weixin.qq.com/cgi-bin/appmsg?'
self.headers = {
'cookie': cookie,
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/74.0.3729.169 Safari/537.36',
'host': 'mp.weixin.qq.com',
'Connection': 'keep-alive',
'Accept': 'application/json, text/javascript, */*; q=0.01'
}
self.data = {
"token": token,
"lang": "zh_CN",
"f": "json",
"ajax": "1",
"action": "list_ex",
"count": "5",
"query": self.search_key,
"fakeid": fakeid,
"type": "9",
}
def parse_articles(self, num):
self.data['begin'] = num
content = requests.get(self.url, headers=self.headers, params=self.data).json()
return content
def get_total(self):
self.data['begin'] = 0
content = requests.get(self.url, headers=self.headers, params=self.data).json()
total = content['app_msg_cnt']
if total % 5:
return int(total / 5) + 1
else:
return int(total / 5)
@staticmethod
def convert_2_time(stamp):
return time.strftime("%Y-%m-%d", time.localtime(stamp))
def get_data(self):
if self.get_total():
for num in range(0, self.get_total() + 1, 5):
for data in self.parse_articles(num)['app_msg_list']:
yield {
"title": data['title'],
"create_time": self.convert_2_time(data['create_time']),
# 摘要
'digest': data['digest'],
'link': data['link']
}
time.sleep(random.randint(1, 3))
else:
print("No search item")
exit()
def write_data(result, filename):
for data in result:
print(data)
with open(filename, 'a', encoding='utf-8') as f:
f.write(json.dumps(data, ensure_ascii=False) + '\n')
4. 模拟登陆
具体操作流程我们都已经知道了,现在就缺两个东西,
cookie
和token
,我们仔细观察首页,token
简直随处可见,html
代码,url
中随处可见,我们就简单的从url中获取即可,cookie
我们通过selenium
登录后获取
I. cookies获取
通过
selenium
调用chrome
浏览器传入用户名以及密码,点击登录后睡眠一定时间给用户扫码,当登录成功后再次访问主页并获取cookie
写入文件(是否写入文件看个人喜好,返回也可以)
def login(username, passwd):
cookies = {}
driver = webdriver.Chrome() # 谷歌驱动
driver.get('https://mp.weixin.qq.com/')
# 用户名
driver.find_element_by_xpath('//input[@name="account"]').clear()
driver.find_element_by_xpath('//input[@name="account"]').send_keys(username)
driver.find_element_by_xpath('//input[@name="password"]').clear()
driver.find_element_by_xpath('//input[@name="password"]').send_keys(passwd)
# 登录
driver.find_element_by_xpath('//a[@class="btn_login"]').click()
time.sleep(20)
# 获取cookie
driver.get('https://mp.weixin.qq.com/')
time.sleep(5)
cookie_items = driver.get_cookies()
for cookie_item in cookie_items:
cookies[cookie_item['name']] = cookie_item['value']
with open('cookie.txt', 'w') as f:
f.write(json.dumps(cookies))
driver.close()
- 这里对
cookie
有一个处理,因为selenium
获取到的cookie
是如下格式的,需要在其中提取出name
和value
,如果是用requests
访问,还需要将字典转为字符串,并且以'; '
分割,别忘记;
后面的空格
II. token获取
读取文件解析
cookie
对主页发起请求,获取到token
后和cookie
一起返回
def get_cookie_token():
url = 'https://mp.weixin.qq.com'
header = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/74.0.3729.169 Safari/537.36',
'host': 'mp.weixin.qq.com',
}
with open('cookie.txt', 'r', encoding='utf-8') as f:
cookie = f.read()
cookies = json.loads(cookie)
response = requests.get(url=url, cookies=cookies)
token = re.findall(r'token=(\d+)', str(response.url))[0]
result = []
for k, v in cookies.items():
result.append(k + '=' + v)
return "; ".join(result), token
热门评论
?