栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

微信公众号爬虫

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

微信公众号爬虫

    使用公众号自带的接口去抓取想要的信息,首先要在自己的公众号中对文章或者公众号进行查找,在数据包中解析出想要的信息,过程中最重要的几个难点:

  • 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后会返回相关搜索项,未指定则默认为空,返回默认的

II. 查看数据内容

III. 流程分析

    通过模拟登陆后获取到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

代码参考Github

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/221383.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号