在后面写爬虫中,需要获取登录的用户的cookies才能进行文章的爬取,所以这里我们需要将cookies获取保存到本地,我测试了一下,cookies的有效时间在两个小时以内,由于学过selenium自动登录,所以我用了selenium做了自动登录保存cookies到本地,自动登录的代码后面还是需要手机扫码的(因为二维码没法破解),自动登录代码如下,比较简单:
下面展示一些 内联代码片
。
from selenium import webdriver
import time
import json
def weiXin_login():
# 定义一个空的字典,存放cookies内容
post = {}
driver = webdriver.Chrome()
driver.get('https://mp.weixin.qq.com/') # 打开微信后台
time.sleep(3)
print("正在输入微信公众号登录账号和密码......")
driver.find_element_by_xpath(".//*[@id='header']/div[2]/div/div/div[2]/a").click()
driver.find_element_by_xpath(".//*[@id='header']/div[2]/div/div/div[1]/form/div[1]/div[1]/div/span/input").clear()
driver.find_element_by_xpath(
".//*[@id='header']/div[2]/div/div/div[1]/form/div[1]/div[1]/div/span/input").send_keys(user)
driver.find_element_by_xpath(".//*[@id='header']/div[2]/div/div/div[1]/form/div[1]/div[2]/div/span/input").clear()
driver.find_element_by_xpath(
".//*[@id='header']/div[2]/div/div/div[1]/form/div[1]/div[2]/div/span/input").send_keys(password)
time.sleep(10)
driver.find_element_by_xpath(".//*[@id='header']/div[2]/div/div/div[1]/form/div[4]/a").click()
time.sleep(20)
print("登录成功")
driver.get('https://mp.weixin.qq.com/') # 重新进后台,获取cookie信息
cookie_items = driver.get_cookies() # 获取cookies信息
# 获取到的cookies是列表形式,将cookies转成json形式并存入本地名为cookie的文本中
for cookie_item in cookie_items:
post[cookie_item['name']] = cookie_item['value']
cookie_str = json.dumps(post)
with open('cookie.txt', 'w+', encoding='utf-8') as f:
f.write(cookie_str)
print("cookies信息已保存到本地")
通过这一步我们就可以将登录的用户cookie保存到本地,给接下来公众号爬取做准备。
1.首先利用fiddler抓包工具,搜索一个公众号:腾讯视频,我们就可以在fiddler中获取到返回的json数据,这里只说爬一个公众号,其实如果爬多个公众号也是一样的过程,只不过我们取第一个公众号而已。
2.fiddler已经帮我们抓到json数据了,接下来我们就通过代码获取json,首先就是拼接请求头headers,请求头参数很多,但其实用到的不多,我刚开始把fiddler得到的请求头都写进去,但是后面做ip代理和UA池的时候发现多了会出现问题,所以headers这里用到Host和User-Agent就可以了。
公众号的路由:https://mp.weixin.qq.com/
想要搜索一个公众号,我们就得知道两个重要的参数,一个是token 和query,其他的参数都可以在fiddler里面复制下来。token是用户登录后的一个唯一标识符,在你登录后会显示,query是你搜索的公众号名。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200721183840467.png
def get_content(query):
# title_header=["发布时间","文章标题","阅读量","文章链接"]
url="https://mp.weixin.qq.com/"
headers={
"Host":"mp.weixin.qq.com",
"User-Agent":user_agent.random +"(KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2469 MMWEBSDK/200601 Mobile Safari/537.36 MMWEBID/3809 MicroMessenger/7.0.16.1680(0x27001033) Process/toolsmp WeChat/arm64 NetType/WIFI Language/zh_CN ABI/arm64"
}
with open("cookies.txt","r",encoding="utf-8")as f:
cookies=f.read()
cookies=json.loads(cookies)
response=requests.get(url=url,headers=headers,cookies=cookies,proxies=ranDom_ip()[0],verify=False)
token=re.findall(r'token=(\d+)?',str(response.url))[0] #获取登录的token信息
search_url='https://mp.weixin.qq.com/cgi-bin/searchbiz?' #公众号超链接搜索路由
search_data={
"action":"search_biz",
"ajax":"1",
"begin":"0",
"random_num": random.random(),
"count":"5",
"f":"json",
"lang":"zh_CN",
"query":query,
"token":token,
} #搜索携带的参数
search_response=requests.get(search_url,headers=headers,cookies=cookies,proxies=ranDom_ip()[0],params=search_data,verify=False)
lists=search_response.json().get('list')[0]#获取第一个搜索的公众号
fakeid=lists['fakeid'] #下面文章中需要的参数
通过上面的代码我们就可以获取到用户登录的token,第一个公众号的fakeid。
要获取一个公众号下面的文章,我们有两个必带的参数,token,fakeid,
文章的路由:https://mp.weixin.qq.com/cgi-bin/appmsg?
我们先通过fiddler点击一个公众号,再去fiddler找相应的路由看参数的变化,主要是看是否获取到公众号下面的文章。
通过分析fiddler是可以获取到json数据,我们可以看到这里需要携带的参数挺多的,那我们在get请求的时候可以拼接带上,然后通过get请求获取腾讯视频里面文章的json数据,接着上面的代码,再写一个get请求
appmsg_url='https://mp.weixin.qq.com/cgi-bin/appmsg?' #文章的路由
appmsg_data={
"action":"list_ex",
"begin":"0",
"count":"5",
"fakeid":fakeid,
"type":"9",
"random_num":random.random(),
"query":"",
"token":token,
"lang":"zh_CN",
"f":"json",
"ajax":"1"
}
appmsg_list=requests.get(appmsg_url,cookies=cookies,headers=headers,proxies=ranDom_ip()[0],params=appmsg_data,verify=False)
从上面的参数我们不难看出,我们现在获取到的只是第一页的文章而已,通过调参数里面的数值,我们可以得到想要页数的文章数据:
到这里的话,通过get下来的json数据,我们就可以将文章的标题和链接获取到,这里如果细节一点的话,还可以获取到发布的时间,这样基本数据就可以ok了,但是这还不能满足需求,因为微信这个反爬特别严重,我亲自测了一下,文章爬取500篇左右就会被识别到禁止获取数据了,所以需要加入UA池和IP代理池,要是想获取到每一篇文章的阅读量的话,我们还需要点击没一篇文章的链接,然后通过post请求获取文章阅读量。
下一篇文章我将会说明怎么获取每篇文章的阅读量和绕过微信反爬
下面是爬取某个公众号文章名、发布时间、链接的完整代码,有兴趣的小伙伴可以看看:
def get_content(query):
# title_header=["发布时间","文章标题","阅读量","文章链接"]
url="https://mp.weixin.qq.com/"
headers={
"Host":"mp.weixin.qq.com",
"User-Agent":user_agent.random +"(KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2469 MMWEBSDK/200601 Mobile Safari/537.36 MMWEBID/3809 MicroMessenger/7.0.16.1680(0x27001033) Process/toolsmp WeChat/arm64 NetType/WIFI Language/zh_CN ABI/arm64"
}
with open("cookies.txt","r",encoding="utf-8")as f:
cookies=f.read()
cookies=json.loads(cookies)
response=requests.get(url=url,headers=headers,cookies=cookies,proxies=ranDom_ip()[0],verify=False)
token=re.findall(r'token=(\d+)?',str(response.url))[0] #获取登录的token信息
search_url='https://mp.weixin.qq.com/cgi-bin/searchbiz?' #公众号超链接搜索路由
search_data={
"action":"search_biz",
"ajax":"1",
"begin":"0",
"random_num": random.random(),
"count":"5",
"f":"json",
"lang":"zh_CN",
"query":query,
"token":token,
} #搜索携带的参数
search_response=requests.get(search_url,headers=headers,cookies=cookies,proxies=ranDom_ip()[0],params=search_data,verify=False)
lists=search_response.json().get('list')[0]#获取第一个搜索的公众号
fakeid=lists['fakeid'] #下面文章中需要的参数
appmsg_url='https://mp.weixin.qq.com/cgi-bin/appmsg?' #文章的路由
appmsg_data={
"action":"list_ex",
"begin":"0",
"count":"5",
"fakeid":fakeid,
"type":"9",
"random_num":random.random(),
"query":"",
"token":token,
"lang":"zh_CN",
"f":"json",
"ajax":"1"
}
appmsg_list=requests.get(appmsg_url,cookies=cookies,headers=headers,proxies=ranDom_ip()[0],params=appmsg_data,verify=False)
max_page=appmsg_list.json()['app_msg_cnt'] #获取文章的总页数
min=int(int(max_page)/5)
a=1
begin=0
with open("./App_sheet/{}公众号文章.csv".format(input_content), "a+", encoding="utf-8", newline="")as f:
write = csv.writer(f)
# write.writerow(title_header)
while min+1>0:
data={
"action": "list_ex",
"begin": "{}".format(str(begin)),
"count": "5",
"fakeid": fakeid,
"random_num": random.random(),
"type": "9",
"query": "",
"token": token,
"lang": "zh_CN",
"f": "json",
"ajax": "1"
}
headers={
"Host":"mp.weixin.qq.com",
"User-Agent":user_agent.random +"(KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2469 MMWEBSDK/200601 Mobile Safari/537.36 MMWEBID/3809 MicroMessenger/7.0.16.1680(0x27001033) Process/toolsmp WeChat/arm64 NetType/WIFI Language/zh_CN ABI/arm64"
}
ip_num=ranDom_ip()[0]
print("正在获取第%s页文章数据"%a)
wenhang_title=requests.get(appmsg_url,cookies=cookies,headers=headers,proxies=ip_num,params=data,verify=False)
sleep(0.5)
reponse=wenhang_title.json()
for dic in reponse['app_msg_list']:
title=dic['title']
link=dic['link']
readnNum=get_readNum(link,headers['User-Agent'],ip_num)
create_time=time.localtime(dic['create_time'])
create_time=time.strftime("%Y-%m-%d",create_time)
write.writerow([create_time,title.strip(),readnNum,link])
begin+=5
min-=1
a+=1
sleep(0.1)
if __name__ == '__main__':
# Wchat_login()
input_content = input("请输入要搜索的公众号:")
content_list = [input_content]
for query in content_list:
get_content(query)