python 爬虫入门到进阶(二)

tsvico Lv5

前言

用 python 发送一个请求

获取百度首页源码

打开了我的 IDEA

接上一篇 入门到放弃一

本文用到的是 python2.7 版本

浏览器的一次请求,输入 url 到地址栏、回车

最后返回一个网页,在请求方式来讲,这是一种 get 请求

在一次请求发送中

image

可以看到还向 www.baidu.com 发送了 User-Agent(简称 UA),Host,cookie 等数据

我们使用模拟请求工具访问

image

可以看到返回的数据实际上时 HTML 代码,只是自动被浏览器解析后才变成了我们看到的网页

下面我们提出第一个问题

爬虫是什么

如果我们把互联网比作一张大的蜘蛛网,数据便是存放于蜘蛛网的各个节点,而爬虫就是一只小蜘蛛,沿着网络抓取自己的猎物(数据)爬虫指的是:向网站发起请求,获取资源后分析并提取有用数据的程序;

从技术层面来说就是 通过程序模拟浏览器请求站点的行为,把站点返回的 HTML 代码 / JSON 数据 / 二进制数据(图片、视频) 爬到本地,进而提取自己需要的数据,存放起来使用;

爬虫的流程是什么

从一个普通用户的角度来看,获取网络内容的方式应该是:

浏览器提交请求 —–> 下载网页代码 —–> 浏览器把代码解析成界面

爬虫要做的就应该是:

模拟浏览器(非浏览器)请求 —–> 获取数据 —–> 解析代码数据提取有效信息 —–> 存储

这么比较是不是爬虫就简单多了

发起请求

使用 http 库向目标站点发起请求,即发送一个 Request

Request 包含:请求头、请求体等

Request 模块缺陷:不能执行 JS 和 CSS 代码

获取响应内容

如果服务器能正常响应,则会得到一个 Response

Response 包含:html,json,图片,视频等

解析内容

解析 html 数据:正则表达式(RE 模块),第三方解析库如 Beautifulsoup,pyquery 等

解析 json 数据:json 模块

解析二进制数据:以 wb 的方式写入文件

保存数据

数据库(MySQL,Mongdb、Redis)

文件

请求的数据包

请求方式

GET、HEAD、PUT、DELETE、POST、OPTIONS
最常用的 GET/POST

GET:GET 可以说是最常见的,它本质就是发送一个请求来获取服务器上的某一资源。资源通过一组 HTTP 头和呈现数据(如 HTML 文本,或者图片或者视频等等)返回给客户端。GET 请求中不会包含呈现数据。

POST:向服务器提交数据。这个方法用途广泛,几乎所有的提交操作都是靠这个完成。

如果你想了解更多,左手 google,右手百度 这里不做过多解释

请求的目标

URL,又叫全球统一资源定位符,每个资源的 URL 都是唯一的

例如 https://www.baidu.com/s?ie=UTF-8&wd=%E5%9B%BE%E7%89%87

‘wd=’之后的一堆字符,其实是‘图片’两个中文被编码后的数据

请求头

User-agent:请求头中如果没有 user-agent 客户端配置,服务端可能将你当做一个非法用户 host;cookies:cookie 用来保存登录信息

一般做爬虫都会加上请求头,Cookie 看目标网站的具体要求,可能还会需要一些其他头

Referrer:访问源至哪里来

User-Agent: 访问的浏览器

请求体

GET 方式没有请求体,所有的数据都在 URL 中

响应状态码

200:代表成功

301:代表跳转

404:文件不存在

403:无权限访问

502:服务器错误

正文

初体验

怎么爬取一个网页呢,换句话说怎么才能获取到一个网站的数据呢

1
2
3
import urllib2
response = urllib2.urlopen("http://www.baidu.com")
print response.read()

没错除去第一行引入,真正的代码只有两行

如果此时你没有安装 IDE,那么用文本编辑器将上面内容保存成 test1.py

一定要自己亲自打一下代码

运行

1
python test1.py

image

后面会讲我的代码为什么多了一行

分析源码

第一行

1
response = urllib2.urlopen("http://www.baidu.com")

这里我们调用了 urllib2 库的 urlopen 方法,urlopen 有三个参数,如下:

1
urlopen(url,data,timeout)

第一个参数 url 上面我们说过了,第二个参数是访问 url 时要传入的数据,第三个为超时设置(超时放弃访问)

第二三个参数可以为空,data 默认为空 None,timeout 默认为 socket._GLOBAL_DEFAULT_TIMEOUT

第一个参数是必须的,返回的值存在 = 左侧的变量中,存储的是 response 对象 打印:

1
print response.read()

response 对象有个 read () 方法,可以返回获取的内容,如果我们不加 read 直接打印会怎么样

image

直接打印出了该对象的描述

构造 Request

urlopen 参数可以传入一个 request 请求,它本身就是一个 Request 类的实例,现在我们来填一下上边挖的坑,我的代码为什么多了一行

1
2
3
4
import urllib2
request = urllib2.Request("http://www.baidu.com")
response = urllib2.urlopen(request)
print response.read()

这就是中间构造了一个 Request 对象,运行结果一致,但是推荐这种写法

POST 和 GET 数据传送

前边提到了 6 中请求方式,最常用的有 post 和 get

很多时候我们获取数据还要进行参数的提交,例如模拟登陆,post 方式会发送数据包,而 get 方式则会把数据放在要访问的 url 中

POST 方式

上面我们说了 data 参数是干嘛的?对了,它就是用在这里的,我们传送的数据就是这个参数 data,下面演示一下 POST 方式。

1
2
3
4
5
6
7
8
import urllib
import urllib2
values = {"username":"xxx","password":"XXXX"}
data = urllib.urlencode(values)
url = "https://passport.csdn.net/account/login?from=http://my.csdn.net/my/mycsdn"
request = urllib2.Request(url,data)
response = urllib2.urlopen(request)
print response.read()

我们引入了 urllib 库,现在我们模拟登陆 CSDN,当然上述代码可能登陆不进去,因为 CSDN 还有个流水号的字段,没有设置全,比较复杂在这里就不写上去了,在此只是说明登录的原理。一般的登录网站一般是这种写法。

我们需要定义一个字典,名字为 values,参数我设置了 username 和 password,下面利用 urllib 的 urlencode 方法将字典编码,命名为 data,构建 request 时传入两个参数,url 和 data,运行程序,返回的便是 POST 后呈现的页面内容。

注意上面字典的定义方式还有一种,下面的写法是等价的

1
2
3
4
5
6
7
8
9
10
import urllib
import urllib2
values = {}
values['username'] = "xxx"
values['password'] = "XXXX"
data = urllib.urlencode(values)
url = "http://passport.csdn.net/account/login?from=http://my.csdn.net/my/mycsdn"
request = urllib2.Request(url,data)
response = urllib2.urlopen(request)
print response.read()

以上方法便实现了 POST 方式的传送

GET 方式

至于 GET 方式我们可以直接把参数写到网址上面,直接构建一个带参数的 URL 出来即可。

1
2
3
4
5
6
7
8
9
10
11
import urllib
import urllib2
values={}
values['username'] = "xxx"
values['password']="XXXX"
data = urllib.urlencode(values)
url = "http://passport.csdn.net/account/login"
geturl = url + "?"+data
request = urllib2.Request(geturl)
response = urllib2.urlopen(request)
print response.read()

你可以 print geturl,打印输出一下 url,发现其实就是原来的 url 加?然后加编码后的参数

1
http://passport.csdn.net/account/login?username=xxx&password=XXXX

和我们平常 GET 访问方式一模一样,这样就实现了数据的 GET 方式传送。

上边是我在网上找的一个例子,登不上的… 你可以自己找个网站,获取源码尝试登陆一下

下一节 带请求头的访问

  • 标题: python 爬虫入门到进阶(二)
  • 作者: tsvico
  • 创建于 : 2018-06-13 16:55:04
  • 更新于 : 2024-06-27 14:07:36
  • 链接: https://blog.tbox.fun/2018/144f4243.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论