一、爬虫概要

1、网络爬虫是什么

百度百科:网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

通俗的讲,爬虫就是能够自动访问互联网并将网站内容下载下来的的程序或脚本,类似一个机器人,能把别人网站的信息弄到自己的电脑上,再做一些过滤,筛选,归纳,整理,排序等等。

网络爬虫的英文即Web Spider,是一个很形象的名字。把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛。网络蜘蛛是通过网页的链接地址来寻找网页,从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。如果把整个互联网当成一个网站,那么网络蜘蛛就可以用这个原理把互联网上所有的网页都抓取下来。

2、网络爬虫的本质及其基本流程

一般情况下,用户获取网络数据有以下两种方式:
(1)借助浏览器:输入url --> 提交请求 --> 下载网页代码 --> 渲染成页面
(2)代码模拟:模拟浏览器发送请求(获取网页代码) --> 提取有用的数据 --> 存储数据
  • 网络爬虫的本质

    • 通过代码模仿浏览器发送请求,即上述方式(2)
  • 基本流程

     向目标站点发送http请求 --> 获取响应内容 --> 解析内容 --> 保存数据
  • 从底层剖析爬虫本质:

     浏览器本质,socket客户端遵循Http协议(通过\r\n分割的规范+请求响应断开连接=>无状态、短连接)

		url = 'www.cnblogs.com'

		sk = socket.socket()
# 连接的过程是:阻塞
sk.connect((url,80)) # HTTP协议
content = "GET /wupeiqi HTTP/1.1\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36\r\n\r\n" %url
sk.sendall(content.encode('utf-8')) # 等待服务端返回内容:阻塞
data = sk.recv(8096)
print(data)
sk.close()

3、Python爬虫必备的知识

  • python

    • 基础
    • 网络编程
  • WEB知识

    • HTML基础
    • CSS基础
    • javascript基础
  • HTTP协议

    • 请求头(一般情况下):

      • user-agent:代指用户的访问设备
      • cookie:服务端在客户端(浏览器)保留的标记
      • refer:请求来源(从哪里请求的)
      • host:
      • content-type:
    • 请求体(数据格式)

      • name=alex&age=18
      • {'name':alex,'age':18}
    • 状态码(重定向302)

      • 响应头中的Location
  • 分析HTTP请求(抓包)

    • chrome
    • fiddler

二、web微信基本通信过程分析

1、微信服务器返回一个会话ID(uuid)

web微信采用扫描二维码登录,不使用用户名密码登录,因此微信服务器需要分配一个唯一的会话ID,用来标识当前的一次登录。GET请求的host及参数如下:
qcode_host = "https://login.wx2.qq.com/jslogin" # GET请求参数
params = {
'appid':"wx782c26e4c19acffb",
'redirect_uri':"https%3A%2F%2Fwx2.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage",
'fun':"new",
'lang':"zh_",
'_':ctime
} # 发送GET请求
res = requests.get(
url=qcode_host,
params=params
)
请求成功,服务器会返回如下的字符串: - window.QRLogin.code = 200; window.QRLogin.uuid = "SCrc8SK6ZG==" - 200表示请求成功,字符串"SCrc8SK6ZG=="是这次请求微信服务器返回的会话ID(uuid)。

2、通过会话ID获得登录二维码

通过浏览器或者代码发送如下GET请求,获取登录二维码:https://login.weixin.qq.com/l/SCrc8SK6ZG==

3、通过长轮询检测是否已扫描二维码,通过响应状态判断是否确认登录

获得二维码后,需要用户在手机端扫描二维码,并确认是否登录,此时浏览器或代码并不知道用户何时操作,因此只有轮询,为了提高轮训效率,web微信采用长轮询的方式,即向如下地址发送GET请求:

check_host = "https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login"
params = {
'loginicon':'true',
'uuid':qcode,
'tip':'0',
'r':'-1036255891',
'_':ctime
} res = requests.get(
url=check_host,
params=params
) - 服务器返回分析:
- window.code=201 说明用户已经完成扫码,但还没确认登录
- window.code=200 window.redirect_uri="https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=A5ncNUM2NJBYNOpJ49Jd38m2@qrticket_0&uuid=Ia7HTPkEdQ==&lang=zh_CN&scan=1485320697" 说明用户已确认登录,保存window.redirect_uri跳转地址 - window.code=408 说明用户未扫码,等待超时,继续轮询

4、获取uin、sid、pass_ticket、skey参数值(注意此处构造的请求地址)

确认登录后,通过向如下redirect_uri地址发送GET请求,获取uin、sid、pass_ticket、skey参数值,便于后续发送请求时使用
- redirect_uri = window.redirect_uri + "&fun=new&version=v2"

5、初使化用户等信息

上述已完成登录过程,下面需要获取用户信息、好友列表、公众号等信息,向如下地址发送POST请求:
init_host = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit" # POST请求参数
params = {
'r': '-1039465096',
'lang': 'zh_CN',
'pass_ticket': ticket_dict.get('pass_ticket')
} # POST请求体
form_data = {
"BaseRequest":{
"DeviceID":"e626652155210212",
"Sid":ticket_dict.get('wxsid'),
"Uin":ticket_dict.get('wxuin'),
"Skey":ticket_dict.get('skey'),
}
} init_res = requests.post(
url=init_host,
params=params, # 第1中json格式数据
# json=data_dict, # 第2中data格式,需要带请求头
data=json.dumps(form_data),
headers={
'Content-Type':'application/json'
}
)
服务器返回用户信息以及同步键值,SyncKey是用户与服务器同步的键值,User是当前登录用户信息。

6、获得所有的好友列表

在上一步骤中已经获得部分好友和公众帐号,如果需要获得完整的好友信息,需要请求如下地址:
- https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?pass_ticket=gzP3GEH0awvApwIttyTwxzAvA27%2BwVAp9tQ1osM%2FLL90XWWU5JeIdNLLVjN%2BJ9bq&skey=@crypt_dcaca546_c69b06b40828731a0acb3235758c0ea6&r=1486119544662 保持之前访问的Cookies不变,在返回的数据中,MemberList包含了所有的好友信息。

7、发送消息

通过向如下地址发送POST请求,发送消息:
https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket=gzP3GEH0awvApwIttyTwxzAvA27%2BwVAp9tQ1osM%2FLL90XWWU5JeIdNLLVjN%2BJ9bq # POST请求体
form_data = {
"BaseRequest": {
"DeviceID": "e626652155210212",
"Sid": ticket_dict.get('wxsid'),
"Uin": ticket_dict.get('wxuin'),
"Skey": ticket_dict.get('skey'),
},
'Msg':{
'ClientMsgId':ctime,
'LocalID':ctime,
'FromUserName':from_user,
'ToUserName':to,
"Content":content,
'Type':1
},
'Scene':0
} send_msg_res = requests.post(
url=send_host,
params =params,
# 若是字符串中含有中文,request传递数据时,将中文转换为字节,无法为我们自动转换编码。直接encoding编码,传递字节,不让requests自动转换
# data可以是字典,字符串,字节,对于字典,字符串直接含有中文不正确,直接转字节传送,py3默认是utf-8,直接传送字节就可以,如果使用json,会将中文转换为Unicode
data=bytes(json.dumps(form_data,ensure_ascii=False),encoding='utf-8')
) 其中BaseRequest都是授权相关的值,与上述获取的值对应。

8、接收消息

检测是否有新消息到来,发送GET请求的地址及请求参数如下:
check_msg_host = "https://webpush.wx2.qq.com/cgi-bin/mmwebwx-bin/synccheck" check_list = [] for item in user_info['SyncKey']['List']:
tmp = "%s_%s" % (item['Key'], item['Val'])
check_list.append(tmp) check_str = "|".join(check_list) # GET请求参数
params = {
'r': int(time.time()),
'skey': ticket_dict.get('skey'),
'sid': ticket_dict.get('wxsid'),
'uin': ticket_dict.get('wxuin'),
'deviceid': "e626652155210212",
'synckey': check_str,
'_':int(time.time())
} check_msg_res = requests.get(
url=check_msg_host,
params=params,
cookies=all_cookies
) 响应的内容如下:
- window.synccheck={retcode:”0”,selector:”2”} 如果retcode不为0,则说明通信有问题。根据selector值,客户端需要作出进一步处理。当selector=2时表示有新消息,此时需要访问另一个接口获取新消息内容,向如下地址发送POST请求: recv_msg_host = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsync" # POST请求参数
params = {
'sid': ticket_dict.get('wxsid'),
'skey': ticket_dict.get('skey'),
'lang':'zh_CN',
} # POST请求数据
form_data = {
'BaseRequest': {
"DeviceID": "e626652155210212",
"Sid": ticket_dict.get('wxsid'),
"Skey": ticket_dict.get('skey'),
"Uin": ticket_dict.get('wxuin'),
},
'SyncKey': user_info.get('SyncKey'),
'rr': int(time.time()) #数据类型
} # 发送POST请求
recv_msg_res = requests.post(
url=recv_msg_host,
params=params,
json=form_data
)

爬虫概要及web微信请求分析的更多相关文章

  1. Web微信模拟

    一.概要 目的:实现一个具有web微信类似功能的项目 框架:Django 模块:render.HttpResponse.BeautifulSoup.re.time.requests.json.rand ...

  2. requests+django+bs4实现一个web微信的功能

    前言: 今天我们利用requests模块+django+bs4浏览器来实现一个web微信的基本功能,主要实现的功能如下 a.实现返回二维码 b.实现手机扫码后二维码变成变成头像 c.实现手机点击登陆成 ...

  3. day37 爬虫2(web微信、高性能相关、Scrapy)

    s16day37 爬虫2 参考博客:http://www.cnblogs.com/wupeiqi/articles/6229292.html 课堂代码:https://github.com/liyon ...

  4. 实现手机扫描二维码页面登录,类似web微信-第一篇,业务分析

    转自:http://www.cnblogs.com/fengyun99/p/3541249.html 关于XMPP组件的文章,先休息两天,好歹已经完整的写了一份. 这两天,先实现一套关于web微信扫描 ...

  5. Python 爬虫五 进阶案例-web微信登陆与消息发送

    首先回顾下网页微信登陆的一般流程 1.打开浏览器输入网址 2.使用手机微信扫码登陆 3.进入用户界面 1.打开浏览器输入网址 首先打开浏览器输入web微信网址,并进行监控: https://wx.qq ...

  6. web微信开发总结

    这两天使用Django开发了web微信,实现了显示联系人以及收发消息的功能. 总结下这过程中使用到的一些知识. 1 http请求 通过chrome浏览器自带的开发者工具查看每次请求的信息,分析请求,包 ...

  7. web微信开发

    群里接收消息时,使用广播,但需要刷新页面才能接收到广播内容. - 轮询: 定时每秒刷新一次,当群不活跃时,群里的每个客户端都在刷新,对服务端压力太大. - 长轮询:客户端连服务端,服务端一直不断开,也 ...

  8. 基于Flask开发web微信

    1. 获取二维码 app.py import re import time import requests from flask import Flask,render_template app = ...

  9. 转 web前端性能分析--实践篇

    当我们知道了web前端性能的关键点后,那么接下来要做的就是如何去具体实施并获取这些关键点的数据了.通过前面的学习知道了不少好的工具,经过对比后个人觉得dynatrace还是不错的. 不仅支持ie,ff ...

随机推荐

  1. python计算时间差的方法

    本文实例讲述了python计算时间差的方法.分享给大家供大家参考.具体分析如下: 1.问题: 给定你两个日期,如何计算这两个日期之间间隔几天,几个星期,几个月,几年? 2.解决方法: 标准模块date ...

  2. Android 5.0 API新增和改进

    开始开发 要构建 Android 5.0 版应用,您必须先下载 Android SDK,然后使用 SDK 管理器下载 Android 5.0 SDK 平台和系统映像. 更新您的目标 API 级别 要进 ...

  3. ARM承认芯片漏洞:披露修复细节

    在谷歌安全研究人员曝光了影响整个芯片产业的CPU设计漏洞后,ARM的Cortex系列处理器也未能逃过一劫.在一篇致开发者的博客文章中,该公司披露了三个已知漏洞的细节——其中两个与Spectre有关.第 ...

  4. php学习十二:其他魔术方法

    __clone():克隆的时候会调用__clone方法: __cal:当类里面没有方法的时候会调用__call方法: __toString:当echo的时候会调用__toString方法: __aut ...

  5. php应该在何时调用mysql_close() ,可能和中断请求有关

    关于php应该在何时调用mysql_close()以及pconnect方式和传统方式有何种区别收藏 以前我一直认为,当php的页面执行结束时,会自动释放掉一切.相信很多人都跟我想的一样.但事实证明并不 ...

  6. c++11——tuple元组

    tuple是一个固定大小的不同类型值的集合,是泛化的 std::pair.可以当做一通用的结构体使用,不需要创建结构体而又获取结构体的特征,在某些情况下可以取代结构体,使程序简洁.直观. 创建tupl ...

  7. 深入浅出Docker(四):Docker的集成测试部署之道

    1. 背景 敏捷开发已经流行了很长时间,如今有越来越多的企业开始践行敏捷开发所提倡的以人为中心.迭代.循序渐进的开发理念.在这样的场景下引入Docker技术,首要目的就是使用Docker提供的虚拟化方 ...

  8. 【文智背后的奥秘】系列篇——分布式爬虫之WebKit

    版权声明:本文由文智原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/139 来源:腾云阁 https://www.qclou ...

  9. shell脚本分析nginx日志

    shell脚本分析nginx日志: name=`awk -F ',' '{print $13":"$32}' $file | awk -F ':' '{print $4}'`ech ...

  10. Jenkins中maven的作用--构建项目(三)

    本文主要根据Jenkins上的日志来继续说明构建项目的过程,上文我们已经讲到构建一个测试环境或单独终端的过程,详情可以了解上篇文章 一.背景介绍 首先看下SVN代码的仓库的结构: 代码仓库里有一个文件 ...