X0
HTTP(HyperText Transfer Protocol)超文本传输协议,是web服务器到web浏览器之间传输的通信规则。
0x01
HTTP协议目前最新版本是1.1,HTTP是一种无状态的协议,只能由客户端发起,服务器端不能主动向客户端发送数据。
应答模型:
Request请求
客户端=============》服务端
《============
Response响应
0x02 HTTP请求
包括三个部分:1、请求行; 2、请求头; 3、请求正文。
实例:
GET /notification/notification_count/ HTTP/1.1 请求行
Host: mp.xxxxxx.com 请求头
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:52.0) Gecko/20100101 Firefox/52.0 (User-Agent代表浏览器标识。)
Accept: application/json, text/javascript, */*; q=0.01 正文
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://mp.toutiao.com/profile_v2/publish
X-Requested-With: XMLHttpRequest
图例brupsuite:
使用python socket测试http响应的效果:
import socket
t_host="www.toutiao.com"
t_port=80
client=socket.socket()
client.connect((t_host,t_port))
client.send("GET / HTTP/1.1\r\nHost:toutiao.com\r\n\r\n")
response=client.recv(4096)
print response
HTTP/1.1 502 Bad Gateway //响应行 HTTP的版, 状态码 502,消息是Bad Gateway
Server: Tengine //响应头 由服务器向客户端发送
Content-Length: 0
Connection: keep-alive
Via: cache5.cn218[0,502-257,M], cache4.cn218[14,1,502001]
X-Swift-Error: dns domain not exist
Timing-Allow-Origin: *
EagleId: 790e0d0415057759521686693e
........由于response获取的字节有限下面是响应正文,是服务器向客户端发送的HTML数据。
EOF:下一遍我将讲述HTTP的请求方法,请期待。
码如下:
import requests from bs4 import BeautifulSoup import pandas as pd #下面是请求数据 url="https://www.163.com/" #设置请求网址为搜索网址 response=requests.get(url) #对163网站就行get请求并将请求结果赋值给response response.encoding="GBK" #设置编码为GBK格式的 html=response.text #获取网页的html源代码并赋值给html #下面是解析数据 soup=BeautifulSoup(html) content=soup.findAll('div') #查找所有的div标签内容并赋值给content print(content) #打印content
代码运行结果如下图所示:
多朋友都听说过Python的大名,而Python也拥有众多的爬虫框架,其中最简单的莫过于requests-html了。它和著名的网络请求库requests是同一个作者,着重于XML数据提取,可以说是最简单的爬虫框架了。
安装这个类库非常简单,直接通过pip就可以安装了。
pip install requests-html
requests-html用起来也十分简单,下面是一个简单例子。照例说明一下,第一段引入了HTMLSession用于创建连接,获取网页数据。第二段创建连接,获取了我的简书用户页面。第三段用xpath语法获取了网页上的用户名,最后打印出来。
from requests_html import HTMLSession
session=HTMLSession()
response=session.get(
'https://www.jianshu.com/u/7753478e1554')
username=response.html.xpath(
'//a[@class="name"]/text()', first=True)
print(username)
看起来是不是很简单?没错,确实很简单,接下来还有一些更加有趣的功能。
编写爬虫之前还要做一件事情,就是分析网页的结构。这个工作其实也很简单,打开你要访问的网页,按F12打开开发人员工具,可以看到最左边有这么一个按钮。点击这个按钮,然后点击网页上你想要查看的网页元素,然后你就可以发现这个元素对应的相关源代码已经为你定位完毕了。
定位按钮
通过这个功能,我们就可以轻松的分析网页,然后通过它的结构来编写爬虫了。
上面的response.html即是网页的根节点HTML节点,在节点对象上可以调用一些方法来检索数据。最常用的方法是find方法,它通过CSS选择器来定位数据。对于上面的例子,可以用find方法改写第三段。
因为所有查找方法返回的结果都是列表,所以如果你确定只需要查找一个,就将first参数设为真来只返回第一个结果。find方法返回的仍然是一个节点,如果只需要节点的内容,调用其text属性即可。
用户名对应的HTML结构如图所示。
代码如下。
username = response.html.find('a.name', first=True).text
除了find方法之外,还可以使用xpath方法用xpath语法来查找节点,正如第一个例子那样。我个人比较喜欢xpath语法,CSS选择器虽然更加流行一些,但是写出来的效果有点怪,不如xpath工整。
同样是这个页面,看看如何获取我的简书的个人简介。网页代码如图所示。
代码如下。
description=response.html.xpath(
'//div[@class="description"]/div[@class="js-intro"]/text()', first=True)
CSS选择器和XPATH语法都不是本篇的主要内容,如果你这方面不太熟悉,最好去看一下相关的教程。当然如果大家有什么疑问的话,也可以提出来。假如大家想看的话,我也可以专门写一篇文章介绍一下这些语法知识。
有些网页利用了前后端分离技术开发的,需要浏览器渲染才能完整显示。如果用爬虫去看的话,只能显示一部分内容。这时候就需要浏览器渲染页面,才能获取完整的页面。用requests-html的话,这个过程非常简单。
首先先来看看一个需要渲染网页的例子。下面的代码访问了我的简书用户页面,然后尝试获取我的所有文章。但是如果你运行这个例子的话,就会发现只能获取前几项。因为简书的页面正是一个典型的需要浏览器渲染的页面,爬虫获取到的网页是不完整的。
from requests_html import HTMLSession
session=HTMLSession()
headers={
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.119 Safari/537.36'
}
url='https://www.jianshu.com/u/7753478e1554'
r=session.get(url, headers=headers)
for a in r.html.xpath('//ul[@class="note-list"]/li/div[@class="content"]/a[@class="title"]'):
title=a.text
link=f'https://www.jianshu.com{a.attrs["href"]}'
print(f'《{title}》,{link}')
那么如何渲染网页来获取完整的结果呢?其实非常简单,在查询HTML节点之前,调用render函数即可。
render函数来使用浏览器渲染
原理也非常简单,第一次调用render的时候,requests-html会在本地下载一个chromium浏览器,用它来渲染网页。如此一来,我们就可以获取到渲染之后的页面了。
但是对于简书这个例子来说还是有些问题,因为如果你在浏览器里打开这个网页的话,会发现一些文章在浏览器下滑页面的时候才开始渲染。不过聪慧的作者早就考虑到这种情况了,render函数支持下滑的参数,设定之后,就会模拟浏览器下滑操作,从而解决了这个问题。
r.html.render(scrolldown=50, sleep=0.2)
不论上面的r.html还是find/xpath函数返回的结果,它们都是节点对象。除了上面介绍的几个提取数据的方法以外,节点对象还有以下一些属性,在我们提取数据的时候也有很大作用。
相较于专业的爬虫框架scrapy,或者仅用于解析XML的解析库BeautifulSoup。requests-html可以是说恰到好处,它没有前者那么难学,也不像后者还需要搭配HTTP请求库才能使用。如果你手头需要临时抓取几个网页,那么requests-html就是你最好的选择。
*请认真填写需求信息,我们会在24小时内与您取得联系。