一、爬虫概要

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. hive的初步认识与hive的本质

    Hive是什么?就从这儿开始学习.... Hive是建立在Hadoop hdfs上的数据仓库基础架构. Hive可以用来数据抽取转换加载(ETL). Hive定义了简单的类SQL查询语句,称为HQL. ...

  2. pl/sql编程2-综合

    案例1,要求:可以向book表添加书,并通过Java程序调用该过程1.1 创建表 ),publishHosuse )); 1.2 编写过程,无返回值 create or replace procedu ...

  3. java运行显示“找不到或无法加载主类”的解决办法(linux)

    要是配置文件的路径问题.打开终端,输入vi ~/.bashrc添加如下代码即可. # set Java environmentJAVA_HOME=/usr/local/java/jdk1.8.0PAT ...

  4. Android 权限信息

    访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限 获取错略位置 android.permiss ...

  5. LLDB调试器

    你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThisThing); 或者跳过一个函数调用来简化程序的行为? NSNu ...

  6. 日记整理---->2016-11-23

    这里放一些jquery的学习知识.可能从一开始就是我一个人单枪匹马,来年不求并肩作战,只愿所向披靡. jquery的学习一 jquery关于ajax的一些学习博客 ajax方法的介绍:https:// ...

  7. Cookie的介绍及使用

    咱们不搞一开始就一大堆理论知识介绍,怕把人讲懵了...... 咱们换一个思维方式——"从现象看本质",先说说我们看到了什么,再从看到的现象中提出问题,最后深入寻找答案. 我们看到的 ...

  8. 监控linux流量python版

    python版监控linux流量 直接上代码,使用OptionParser来传入参数 #coding:utf-8 #------------- #Author:Hu #Data:20150520 #- ...

  9. oracle的分页查询,mabatis的sql配置

    <select id="getCardcaseByPage" resultType="Cardcase" > select * from ( sel ...

  10. linux设置安全连接设置(私钥)

    1.私钥制作工具:puttygen 连接工具:xshell和putty. 2.制作私钥和公钥 a.打开puttygen点击Generate生产公钥和私钥(鼠标需要晃动,进度条才会前进) b. 设置标签 ...