• 当我们在谈论爬虫时我们在谈论什么(一)


    从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
    Host: {}
    
    '.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 Host: www.baidu.com 这一报文,它在接受后返回了以下报文(省略部分)和网站内容。

    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协议对于在实际爬取过程中抓包分析是有所帮助的。

       

  • 相关阅读:
    selenium学习笔记05-selenium操作from表单
    selenium学习笔记04-webdriver核心方法的属性和使用
    selenium学习笔记03-selenium webdriver工作原理
    selenium学习笔记02-selenium定位的八大方法
    selenium学习笔记01
    微服务质量保证学习笔记(一)
    pytest,setup和teardown
    pytest用例编写规则、执行测试
    速耀达账套备份与恢复(速达二次开发)
    速耀达系统权限设置(速达二次开发)
  • 原文地址:https://www.cnblogs.com/lynsyklate/p/6675894.html
Copyright © 2020-2023  润新知