使用工具:Charles、mumu6模拟器、pycharm
PS:本篇文章只是爬取壹心理APP的热搜问答内容。文章若有不足之处,还请指出
首先在进行逆向爬取时得先配置好使用工具,其中charles、mumu6模拟器网上均有配置教程,本文不在进行赘述。
最开始我们打开抓包软件Charles
这里是Charles的初始界面,经过配置后模拟器上所有网络都会通过这里 ,打开壹心理APP后,我们可以看到网络包,此时就可以开始进行选择抓包
此时我们就可以选择需要爬取内容的过程链接
输入到任意浏览器,就获取到了热搜问题的url页面,从这里我们可以找到每一个问答的id等等之类的信息,下一步我们继续找寻规律
当点进内容的时候,我们的Charles同样抓到了内容的url
我们将提取出来的url输到浏览器打开,得到内容页面
这个时候我们找寻前面获取的两次url之间的关系,看看能否串联上,我们发现第一次得到的url里面有question_id是连接第二次url的信息
得到规律我们实验规律输入第二个问题的question_id成功得到第二个热搜的问答界面
我们的目的是将每一个问题以及里面的回答和作者之类的信息写入txt,这时我们点击问答页面里的回答界面,得到第三层url,这里我们得到这个问题的总界面之后可以F12进入开发者工具进行一个网络监察,和普通爬虫的内容一致,我们首先还是要获取列表信息,下面是当前问答的回答列表,列表中包含最大20的数量
用浏览器将url打开,得到内容页面
在这个地方我们再次找寻页码规律,发现此处有页码限制,因此我们若要爬取全部内容的话可以尝试一个很大页码,当跳到这个页码的时候是没有内容的,我们就可以跳出循环
附上完整代码:
# -*- coding: utf-8 -*-
import re
import requests
from bs4 import BeautifulSoup
import json
import time
headers= {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'
}
def start():
# 热搜的所有页码
url = [f'https://m.xinli001.com/qa/get-qa-tag-data-list.json?token=6c27eb535bd62cb65505710b0d63bd25&format=json&sshzv=0&page={i}&tag_name=hot_question'
for i in range(5)]
for i in url:
resp = requests.get(i, headers=headers)
s = resp.text.encode('utf-8').decode('unicode_escape')
json1 = json.loads(s, strict=False)
# 获取所有标题
ques_list = json1["data"]
for x in ques_list:
ques_id = x['question_id']
title = x['title']
print(ques_id)
url_parse(ques_id, title)
# 如果没有内容证明爬取完成,退出循环
if len(ques_list) == 0:
break
def url_parse(id, title):
detal = [f'https://yiapp.xinli001.com/qaQuestion/getAnswerList?_version=8.7.5&_platform=android&id={id}&pageNo={i+1}&pageSize=20×tamp=1688272855432&sign=783ef2bede39530caaad5b3c1da46f92' for i in range(100)]
for item in detal:
print(item)
resp = requests.get(item, headers=headers)
# s = resp.text.encode('utf-8').decode('unicode_escape')
pattern1 = '"answer":(.*?),'# 内容
pattern2 = '"nickname":(.*?),'# 作者姓名
pattern3 = '"createTime":(.*?)}'# 发布时间
# 提取匹配的内容
match1 = re.findall(pattern1, resp.text, re.S)
match2 = re.findall(pattern2, resp.text, re.S)
match3 = re.findall(pattern3, resp.text, re.S)
for i in range(len(match1)):
writes(match1[i], match2[i], match3[i], title)
# 如果没有内容证明爬取完成,退出循环
if len(match1) == 0:
break
print(match2)
def writes(content, author, time, title):
f.write(f'问题:{title}\n回答者:{author}\n时间:{time}\n内容:{content}\n\n')
if __name__ == '__main__':
with open('热搜1.txt', mode='w', encoding='utf-8') as f:
start()