querylist采集微信公众号文章(一个就是ip代理的质量不行,哪里不行呢?)

优采云 发布时间: 2022-02-22 21:21

  querylist采集微信公众号文章(一个就是ip代理的质量不行,哪里不行呢?)

  关注上一篇未完成的爬虫项目,继续更新最终代码片段

  最近比较忙,没时间更新文章的下一篇。就在这几天,有时间重新调整代码,更新里面的细节。发现调整代码有很多问题,主要是ip代理质量不好,哪里不好,往下看就知道了。三、获取每篇文章文章的阅读和点赞数

  想要获取文章的阅读量,在微信公众平台里面直接点击,是获取不了文章的阅读量的,测试如下:

  

  然后我们可以去fiddler查看这个文章的包,可以看到这个包是

  文章的内容可以从body的大小来判断,也就是文章的内容。

  

  但是我们无法从这个路由中获取文章的阅读量,因为这个请求是一个get请求。如果要获取文章的阅读点赞,第一个请求是post请求,然后需要携带三个重要参数pass_ticket、appmsg_token、phoneCookie。要获取这三个参数,我们要把公众号中的文章放到微信中点击,然后从fiddler查看抓包情况。

  

  我们去fiddler看一下抓包情况:我们可以看到上面还有一个get请求,但是下面添加了一个post请求的内容,然后看一下携带的参数,这三个是重要的得到我们想要的阅读量参数,以及响应的内容,可以看出已经获取到文章的阅读量信息。现在我们可以拼接参数来发送请求了。

  

  #获取文章阅读量

def get_readNum(link,user_agent):

pass_ticket ="N/Sd9In6UXfiRSmhdRi+kRX2ZUn9HC5+4aAeb6YksHOWNLyV3VK48YZQY6oWK0/U"

appmsg_token = "1073_N8SQ6BkIGIQRZvII-hnp11Whcg8iqFcaN4Rd19rKluJDPVMDagdss_Rwbb-fI4WaoXLyxA244qF3iAp_"

# phoneCookie有效时间在两个小时左右,需要手动更新

phoneCookie = "rewardsn=; wxtokenkey=777; wxuin=2890533338; devicetype=Windows10x64; version=62090529; lang=zh_CN; pass_ticket=N/Sd9In6UXfiRSmhdRi+kRX2ZUn9HC5+4aAeb6YksHOWNLyV3VK48YZQY6oWK0/U; wap_sid2=CNqTqOIKElxWcHFLdDFkanBJZjlZbzdXVmVrejNuVXdUb3hBSERDTTBDcH*敏*感*词*VAxTTFIeEpwQmdrWnM1TWRFdWtuRUlSRDFnUzRHNkNQZFpVMXl1UEVYalgyX1ljakVFQUFBfjCT5bP5BTgNQAE="

mid = link.split("&")[1].split("=")[1]

idx = link.split("&")[2].split("=")[1]

sn = link.split("&")[3].split("=")[1]

_biz = link.split("&")[0].split("_biz=")[1]

url = "http://mp.weixin.qq.com/mp/getappmsgext"

headers = {

"Cookie": phoneCookie,

"User-Agent":user_agent

}

data = {

"is_only_read": "1",

"is_temp_url": "0",

"appmsg_type": "9",

'reward_uin_count': '0'

}

params = {

"__biz": _biz,

"mid": mid,

"sn": sn,

"idx": idx,

"key": '777',

"pass_ticket": pass_ticket,

"appmsg_token": appmsg_token,

"uin": '777',

"wxtoken": "777"

}

success = False

a=1

while not success:

ip_num = ranDom_ip()[0] # 使用不同的ip进行阅读、点赞量的获取

try:

print("获取阅读量使用ip:%s"%ip_num)

content = requests.post(url, headers=headers, data=data, params=params, proxies=ip_num,timeout=6.6)#设置超时时间5秒

time.sleep(4)

content = content.json()

print(link)#文章链接

print(content)#文章内容

if 'appmsgstat' in content:

readNum = content["appmsgstat"]["read_num"]

like_num=content["appmsgstat"]["old_like_num"] #点赞量

zai_kan=content["appmsgstat"]["like_num"] #在看量

else:

readNum = 0

like_num = 0

success=True

return readNum, like_num

except:

print("获取阅读量ip出现问题,更换ip进入第二次循环获取!!!")

a+=1

# if a%5==0:

content = requests.post(url, headers=headers, data=data, params=params,timeout=5)

time.sleep(3)

content = content.json()

print(link) #文章链接

print(content)#文章内容

if 'appmsgstat' in content:

readNum = content["appmsgstat"]["read_num"]

like_num = content["appmsgstat"]["old_like_num"] # 点赞量

zai_kan = content["appmsgstat"]["like_num"] # 在看量

else:

print('文章阅读点赞获取失败!')

readNum=0

like_num=0

# else:

# continue

return readNum, like_num

  需要注意的是,在这三个重要参数中,phoneCookie 是时间敏感的,需要手动更新,这是最麻烦的,就像 cookie 一样。通过传入的文章链接,我们可以在链接中提取一些有用的参数,用于后期拼接post请求。不好,所以代码略显冗余(需要改进)。

  四、使用UA代理和IP代理设置每个文章的爬取速度

  通过以上操作,我们基本可以爬取文章的链接、标题、链接,完成初步需求:

  

  但是我在开心爬的时候发现很快就被反爬发现了,直接屏蔽了我公众号的请求。

  

  这时候就想到了ip proxy来识别我们是否反爬,主要是从ip和UA,所以后来做了一个ip代理池,从一些ip网站爬取ip,通过了代码大赛选择有用的 IP 形成 IP 池。贡献一段我爬ip的代码,感兴趣的朋友可以直接试试:

  import requests

from bs4 import BeautifulSoup

import json

import random

import re

ip_num=[]

url="http://www.66ip.cn/1.html"

headers={

"Host": "www.66ip.cn ",

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36",

"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",

"Referer": "http://www.66ip.cn/index.html",

"Cookie": "Hm_lvt_1761fabf3c988e7f04bec51acd4073f4=1595575058,1595816310; Hm_lpvt_1761fabf3c988e7f04bec51acd4073f4=1595832351",

}

content=requests.get(url,headers=headers)

content.encoding="gbk"

html=BeautifulSoup(content.text,"html.parser")

# print(html)

content=html.find_all("table",{"border":"2px"})

ip=re.findall('(\d{1,4}.\d{1,4}.\d{1,4}.\d{1,4})',str(content))

port=re.findall('(\d{1,5})',str(content))

for i in range(len(port)):

ip_num.append(ip[i]+":"+port[i])

proxies = [{'http':ip_num[num]} for num in range(len(ip_num))]

for i in range(0, len(ip_num)):

proxie = random.choice(proxies)

print("%s:当前使用的ip是:%s" % (i, proxie['http']))

try:

response = requests.get("http://mp.weixin.qq.com/", proxies=proxie, timeout=3)

print(response)

if response.status_code == 200:

# with open('ip.txt', "a", newline="")as f:

# f.write(proxie['http'] + "\n")

print("保存成功")

except Exception as e:

print("ip不可用")

  我将过滤掉网站的ip,保存在本地,然后通过写一个函数来创建一个ip地址:

  #代理池函数

def ranDom_ip():

with open('ip.txt',"r")as f:

ip_num=f.read()

ip_list=ip_num.split("\n")

num=random.randint(0,len(ip_list)-1)

proxies = [{'http': ip_list[num]}]

return proxies

  然后在函数循环中调用这个ip代理的函数,就可以不断更新自己使用的ip。这是给你的流程图,所以我们可以知道在哪里使用ip代理功能。

  

  通过将以上三个地方加入到我们使用的ip池中,不断变化的ip就是成功绕过反爬的点。当我们不断更改 ip 时,我仍然感到有点不安全。我觉得UA也需要不断更新,所以我导入了一个ua代理池

  from fake_useragent import UserAgent #导入UA代理池

user_agent=UserAgent()

  但需要注意的是,我们不能更改headers中的所有UA,我们只能添加UA代理的一部分,因为公众号的请求是由两部分组成的,我们只能添加前半部分。

  

  就像下面的请求头一样,我们的Ua代理只能替换前半部分,这样Ua也是不断变化的,而且变化的位置和上面ip函数的位置一样,我们就可以实现ip,UA在之后每个请求都是不同的。

   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和ua是不断变化的,但是你公众号的cookie不能被改变。如果爬取速度过快,会识别出访问你公众号某个界面的频率太快,直接禁止你公众号搜索的界面文章,所以我们需要做一个请求延迟,那么在这个过程中我们哪里可以做得更好呢?可以在流程图中标记的位置进行延迟。

  

  这样既能控制速度,又能防止本地ip和ua被发现,妙不可言。缺点是我没有找到高质量的ip池。我用的是free ip,所以很多都是在换ip的过程中拿不到的。读取量方面(穷人叹),如果有高级IP代理池,速度是非常快的。完整的代码不会在这里粘贴。有兴趣我可以私发。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线