1. 首页
  2. Python

python爬虫简单总结(一)

爬虫?什么时爬虫?

我个人理解的爬虫就是:爬虫是一个模拟浏览器进行HTTP 请求的过程,快速获取我们想要的数据。

HTTP

HTTP协议请求本身是非常简单的,主要是,由客户端主动发送请求,服务器接收请求处理后返回响应结果,同时HTTP,是一种无状态,无连接,的超文本传输协议,协议本身不记录客户端的历史请求记录。

python爬虫简单总结(一)

HTTP 请求由3部分组成,分别是请求行、请求首部、请求体,首部和请求体是可选的,并不是每个请求都需要的。

python爬虫简单总结(一)

现在我们用 Python 提供的最原始API socket 模块来模拟向服务器发起一个 HTTP 请求

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:

# 1. 与服务器建立连接

s.connect((“www.seriot.ch”, 80))

# 2. 构建请求行,请求资源是 index.php

request_line = b”GET /index.php HTTP/1.1″

# 3. 构建请求首部,指定主机名

headers = b”Host: seriot.ch”

# 4. 用空行标记请求首部的结束位置

blank_line = b”rn”

# 请求行、首部、空行这3部分内容用换行符分隔,组成一个请求报文字符串

# 发送给服务器

message = b”rn”.join([request_line, headers, blank_line])

s.send(message)

# 服务器返回的响应内容稍后进行分析

response = s.recv(1024)

print(response)

HTTP响应

服务端接收请求并处理后,返回响应内容给客户端,同样地,响应内容也必须遵循固定的格式浏览器才能正确解析。HTTP 响应也由3部分组成,分别是:响应行、响应首部、响应体,与 HTTP 的请求格式是相对应的。

python爬虫简单总结(一)

Request库

requests 实现了 HTTP 协议中绝大部分功能,它提供的功能包括 Keep-Alive、连接池、Cookie持久化、内容自动解压、HTTP代理、SSL认证、连接超时、Session等很多特性,最重要的是它同时兼容 python2 和 python3。

requests 的安装可以直接使用 pip 方法:pip install requests

>>> import requests

# GET 请求

>>> response = requests.get(“https://foofish.net”)

请求返回 Response 对象,Response 对象是 对 HTTP 协议中服务端返回给浏览器的响应数据的封装,响应的中的主要元素包括:状态码、原因短语、响应首部、响应体等等,这些属性都封装在Response 对象中。

# 状态码

>>> response.status_code

200

# 原因短语

>>> response.reason

‘OK’

# 响应首部

>>> for name,value in response.headers.items():

…    print(“%s:%s” % (name, value))

Content-Encoding:gzip

Server:nginx/1.10.2

Date:Thu, 06 Apr 2017 16:28:01 GMT

# 响应内容

>>> response.content

requests 除了支持 GET 请求外,还支持 HTTP 规范中的其它所有方法,包括 POST、PUT、DELTET、HEADT、OPTIONS方法。

>>> r = requests.post(‘http://httpbin.org/post’, data = {‘key’:’value’})

>>> r = requests.put(‘http://httpbin.org/put’, data = {‘key’:’value’})

>>> r = requests.delete(‘http://httpbin.org/delete’)

>>> r = requests.head(‘http://httpbin.org/get’)

>>> r = requests.options(‘http://httpbin.org/get’)

构建请求查询参数

>>> args = {“p”: 4, “s”: 20}

>>> response = requests.get(“http://fav.foofish.net”, params = args)

>>> response.url

‘http://fav.foofish.net/?p=4&s=2’

requests 可以很简单地指定请求首部字段 Headers,比如有时要指定 User-Agent 伪装成浏览器发送请求,以此来蒙骗服务器。直接传递一个字典对象给参数 headers 即可。

>>> r = requests.get(url, headers={‘user-agent’: ‘Mozilla/5.0’})

requests 可以非常灵活地构建 POST 请求需要的数据,如果服务器要求发送的数据是表单数据,则可以指定关键字参数 data,如果要求传递 json 格式字符串参数,则可以使用json关键字参数,参数的值都可以字典的形式传过去。

作为表单数据传输给服务器

>>> payload = {‘key1’: ‘value1’, ‘key2’: ‘value2’}

>>> r = requests.post(“http://httpbin.org/post”, data=payload)

作为 json 格式的字符串格式传输给服务器

>>> import json

>>> url = ‘http://httpbin.org/post’

>>> payload = {‘some’: ‘data’}

>>> r = requests.post(url, json=payload)

HTTP返回的响应消息中很重要的一部分内容是响应体,响应体在 requests 中处理非常灵活,与响应体相关的属性有:content、text、json()。

content 是 byte 类型,适合直接将内容保存到文件系统或者传输到网络中

>>> r = requests.get(“https://pic1.zhimg.com/v2-2e92ebadb4a967829dcd7d05908ccab0_b.jpg”)

>>> type(r.content)

<class ‘bytes’>

# 另存为 test.jpg

>>> with open(“test.jpg”, “wb”) as f:

…    f.write(r.content)

text 是 str 类型,比如一个普通的 HTML 页面,需要对文本进一步分析时,使用 text。

>>> r = requests.get(“https://foofish.net/understand-http.html”)

>>> type(r.text)

<class ‘str’>

>>> re.compile(‘xxx’).findall(r.text)

如果使用第三方开放平台或者API接口爬取数据时,返回的内容是json格式的数据时,那么可以直接使用json()方法返回一个经过json.loads()处理后的对象。

>>> r = requests.get(‘https://www.v2ex.com/api/topics/hot.json’)

>>> r.json()

[{‘id’: 352833, ‘title’: ‘在长沙,父母同住…

当爬虫频繁地对服务器进行抓取内容时,很容易被服务器屏蔽掉,因此要想继续顺利的进行爬取数据,使用代理是明智的选择。如果你想爬取墙外的数据,同样设置代理可以解决问题,requests 完美支持代理。

import requests

proxies = {

‘http’: ‘http://10.10.1.10:3128’,

‘https’: ‘http://10.10.1.10:1080’,

}

requests.get(‘http://example.org’, proxies=proxies)

Session

HTTP协议是一中无状态的协议,为了维持客户端与服务器之间的通信状态,使用 Cookie 技术使之保持双方的通信状态。

有些网页是需要登录才能进行爬虫操作的,而登录的原理就是浏览器首次通过用户名密码登录之后,服务器给客户端发送一个随机的Cookie,下次浏览器请求其它页面时,就把刚才的 cookie 随着请求一起发送给服务器,这样服务器就知道该用户已经是登录用户。

import requests

# 构建会话

session  = requests.Session()

# 登录url

session.post(login_url, data={username, password})

# 登录后才能访问的url

r = session.get(home_url)

session.close()

构建一个session会话之后,客户端第一次发起请求登录账户,服务器自动把cookie信息保存在session对象中,发起第二次请求时requests 自动把session中的cookie信息发送给服务器,使之保持通信状态。

BeautifulSoup

网络请求库神器 Requests ,请求把数据返回来之后就要提取目标数据,不同的网站返回的内容通常有多种不同的格式,一种是 json 格式,这类数据对开发者来说最友好。另一种 XML 格式的,还有一种最常见格式的是 HTML 文档,今天就来讲讲如何从 HTML 中提取出感兴趣的数据

BeautifulSoup 是一个用于解析 HTML 文档的 Python 库,通过 BeautifulSoup,你只需要用很少的代码就可以提取出 HTML 中任何感兴趣的内容,此外,它还有一定的 HTML 容错能力,对于一个格式不完整的HTML 文档,它也可以正确处理。

安装 BeautifulSoup

pip install beautifulsoup4

BeautifulSoup3 被官方放弃维护,你要下载最新的版本 BeautifulSoup4。

HTML 标签

学习 BeautifulSoup4 前有必要先对 HTML 文档有一个基本认识,如下代码,HTML 是一个树形组织结构

<html>

<head>

<title>hello, world</title>

</head>

<body>

<h1>BeautifulSoup</h1>

<p>如何使用BeautifulSoup</p>

<body>

</html>

它由很多标签(Tag)组成,比如 html、head、title等等都是标签

一个标签对构成一个节点,比如 <html>…</html>是一个根节点

节点之间存在某种关系,比如 h1 和 p 互为邻居,他们是相邻的兄弟(sibling)节点

h1 是 body 的直接子(children)节点,还是 html 的子孙(descendants)节点

body 是 p 的父(parent)节点,html 是 p 的祖辈(parents)节点

嵌套在标签之间的字符串是该节点下的一个特殊子节点,比如 “hello, world” 也是一个节点,只不过没名字。

构建一个 BeautifulSoup 对象需要两个参数,第一个参数是将要解析的 HTML 文本字符串,第二个参数告诉 BeautifulSoup 使用哪个解析器来解析 HTML。

解析器负责把 HTML 解析成相关的对象,而 BeautifulSoup 负责操作数据(增删改查)。“html.parser” 是 Python 内置的解析器,“lxml” 则是一个基于c语言开发的解析器,它的执行速度更快,不过它需要额外安装

通过 BeautifulSoup 对象可以定位到 HTML 中的任何一个标签节点。

from bs4 import BeautifulSoup

text = “””

<html>

<head>

<title >hello, world</title>

</head>

<body>

<h1>BeautifulSoup</h1>

<p class=”bold”>如何使用BeautifulSoup</p>

<p class=”big” id=”key1″> 第二个p标签</p>

<a href=”http://foofish.net”>python</a>

</body>

</html>

“””

soup = BeautifulSoup(text, “html.parser”)

# title 标签

>>> soup.title

<title>hello, world</title>

# p 标签

>>> soup.p

<p class=”bold”>u5982u4f55u4f7fu7528BeautifulSoup</p>

# p 标签的内容

>>> soup.p.string

u’u5982u4f55u4f7fu7528BeautifulSoup’

遍历文档树,顾名思义,就是是从根节点 html 标签开始遍历,直到找到目标元素为止,遍历的一个缺陷是,如果你要找的内容在文档的末尾,那么它要遍历整个文档才能找到它,速度上就慢了。因此还需要配合第二种方法。

通过遍历文档树的方式获取标签节点可以直接通过 .标签名的方式获取,例如:

获取 body 标签:

>>> soup.body

<body>n<h1>BeautifulSoup</h1>n<p class=”bold”>u5982u4f55u4f7fu7528BeautifulSoup</p>n</body>

获取 p 标签

>>> soup.body.p

<p class=”bold”>u5982u4f55u4f7fu7528BeautifulSoup</p>

获取 p 标签的内容

>>> soup.body.p.string

u5982u4f55u4f7fu7528BeautifulSoup

搜索文档树是通过指定标签名来搜索元素,还可以通过指定标签的属性值来精确定位某个节点元素,最常用的两个方法就是 find 和 find_all。这两个方法在 BeatifulSoup 和 Tag 对象上都可以被调用。

find_all()

find_all( name , attrs , recursive , text , **kwargs )

find_all 的返回值是一个 Tag 组成的列表,方法调用非常灵活,所有的参数都是可选的。

第一个参数 name 是标签节点的名字。

# 找到所有标签名为title的节点

>>> soup.find_all(“title”)

[<title>hello, world</title>]

>>> soup.find_all(“p”)

[<p class=”bold”>xc8xe7xbaxcexca….</p>,

<p class=”big”> xb5xdaxb6xfexb8xf6p…</p>]

BeatifulSoup 是一个用于操作 HTML 文档的 Python 库,初始化 BeatifulSoup 时,需要指定 HTML 文档字符串和具体的解析器。它有3类常用的数据类型,分别是 Tag、NavigableString、和 BeautifulSoup。查找 HTML元素有两种方式,分别是遍历文档树和搜索文档树,通常快速获取数据需要二者结合。

本文来自投稿,不代表程序员编程网立场,如若转载,请注明出处:http://www.cxybcw.com/203878.html

联系我们

13687733322

在线咨询:点击这里给我发消息

邮件:1877088071@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code