首页 > 技术文章 > 当我们在谈论爬虫时我们在谈论什么(一)

lynsyklate 2017-04-06 22:55 原文

从HTTP协议说起

每一个网站就是一张巨大的蜘蛛网,有的连向别的网站的外链,就如同一根细丝连向了别的蜘蛛织成的网,而爬虫则沿着这张网络不断爬取信息。想要了解爬虫我们就必须了解他获取信息的方式,也就是HTTP协议。

我们可以把连接网站的过程看作电视购物,网站的服务器如同电视购物的卖家一直在电话旁边等候着客户的电话,而我们用户链接网站的过程,相当于给卖家打电话。

那么问题来了,服务器可能同时搭建了不止一个网站,或者一个网站有很多子页面,我怎么知道你需要哪个呢?不告诉卖家你需要什么货物,卖家是无法给你发货的。因此我们需要传递一条信息给卖家告诉他我们要什么。

请求信息的格式

GET /index.html

这就是最简单的一条信息,告诉服务器,我们需要你网站的index页面。

但是正如前面所说的,有的服务器可能不止有一个网站,如同一个地址可能同时开了很多家店,服务器此时就会疑惑了,哪个网站的index呢?

因此我们引入了Host

GET /index.html HTTP/1.0
Host: www.fuck.com
Accept: */*

 

此时我们就知道你是要fuck这个网站的index页面了

当然HTTP协议虽然不复杂,也有很多的内容,可以参考阮一峰文章做粗略的了解
HTTP 协议入门
也可以阅读《HTTP权威指南》作为参考

python连接网站

既然想要获取网站的内容,我们就得向他发送get的信息,爬虫是如何发送的呢?

假如你有网络编程的基本知识,那么下面的文章你可以跳过,如果对于网络编程不够了解,或者对于python不够熟练,可以先了解下面的文章
python之socket编程
socket python documention

import socket

def fetch(url, port):
    sock = socket.socket()
    sock.connect((url, port))
    request = 'GET / HTTP/1.0\r\nHost: {}\r\n\r\n'.format(url)
    sock.send(request.encode("ascii"))
    response = b''
    chunk = sock.recv(4096)
    while chunk:
        response += chunk
        chunk = sock.recv(4096)
    return response

print(fetch("www.baidu.com", 80))

 

在上面的代码中我们获取了www.baiducom这个页面的所有内容(之所以选择百度,是因为它流量大,且主页并没有做任何反爬虫的措施。)我们使用socket向他发送了GET / HTTP/1.0\r\nHost: www.baidu.com\r\n\r\n这一报文,它在接受后返回了以下报文(省略部分)和网站内容。

HTTP/1.1 200 OK
Date: Thu, 06 Apr 2017 03:05:27 GMT
Content-Type: text/html
Content-Length: 14613

 

这个报文告诉了我们对于网站的请求成功了,以及网站返回的类型是html以及返回类型的大小

模拟真实用户的请求

如何才能使自己发送的报文和浏览器发送的一致呢

打开浏览器的开发者面板(F12)
选择网络

 

输入你想要爬取的网址,网络一栏如上图,会出现你与网站做的各种信息的交流
点开任意一个查看它的请求头
(FIirefox)

 


(Chrome)

 


只要在socket中填入这些信息,那么在向网站请求这一步,你所做的其实与浏览器并没有区别

当然,在实际的编程中我们不可能使用这么原始的方式,python的requests库能够简单的模拟这些请求。

比如在header中加入useragent这一信息

import requests

headers={"User-Agent":"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"}
res = requests.get("http://www.baidu.com",headers=headers)

 

我们可以查看requests做了什么

# 查看发送的请求
res.request.headers
#查看网站返回的报头
res.headers

 

requests库入手简单,代码清晰,但是也因此封装了许多细节,从socket入手了解HTTP协议对于在实际爬取过程中抓包分析是有所帮助的。

   

推荐阅读