Date: 2019-06-19

Author: Sun

本节要学习的库有:

网络库:requests

页面解析库:Beautiful Soup

1 Requests库

​ 虽然Python的标准库中 urllib 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 “HTTP for Humans”,说明使用更简洁方便。

​ Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。Requests 的哲学是以 PEP 20 的习语为中心开发的,所以它比 urllib 更加 Pythoner。更重要的一点是它支持 Python3 哦!

​ Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用:)

​ Requests 继承了urllib的所有特性。Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动确定响应内容的编码,支持国际化的 URL 和 POST 数据自动编码

​ requests 的底层实现其实就是 urllib3

​ Requests的文档非常完备,中文文档也相当不错。Requests能完全满足当前网络的需求,支持Python 2.6—3.6

1.1 安装 Requests

pip install requests  

Requests官方文档:

http://docs.python-requests.org/zh_CN/latest/user/quickstart.html

http协议测试网站:

http://httpbin.org/

1.2 基本用法:

import requestsresponse = requests.get('http://www.baidu.com')
print(response.request.url) # 等同于response.url
print(response.status_code)
#请求头是请求头,响应头是响应头
print(response.headers['content-type'])    #不区分大小写
print(response.encoding)
print(response.text)       #获取文本,一般情况自动解码

1.3 请求方法

​ Requests的请求不再像urllib一样需要去构造各种Request,opener和handler,使用Requests构造的方法,并在其中传入需要的参数即可
每一个请求方法都有一个对应的API,比如GET请求就可以使用get()方法

​ POST请求就可以使用post()方法,并且将需要提交的数据传递给data参数即可

​ 设置访问超时,设置timeout参数即可

requests.get(‘http://github.com’,timeout=0.01)

具体用例说明

import requests
response = requests.get('https://httpbin.org/get')        #拉数据
response = requests.post('http://gttpbin.org/post',data={'key': 'value'})   #推数据# - post请求四种传送正文方式:
#   - 请求正文是application/x-www-form-urlencoded
#   - 请求正文是multipart/form-data
#   - 请求正文是raw
#   - 请求正文是binaryresponse = requests.put('http://httpbin.org/put',data={'key':'value'})
response = requests.delete('http://httpbin.org/delete')
response = requests.head('http://httpbin.org/get')
response = requests.options('http://httpbin.org/get')

1.4 传递URL参数

(1)传递URL参数也不用再像urllib中那样需要去拼接URL,而是简单的构造一个字典,并在请求时将其传递给params参数

(2)有时候我们会遇到相同的url参数名,但又不同的值,而Python的字典又不支持键的重名,可以把键的值用列表表示

#传递URL参数也不用再像urllib中那样需要去拼接URL,而是简单的构造一个字典,并在请求时将其传递给params参数
import requests
params = {'key1':'value1','key2':'value2'}
response = requests.get('http://httpbin.org/get',params=params)
#有时候我们会遇到相同的url参数名,但又不同的值,而Python的字典又不支持键的重名,可以把键的值用列表表示
params = {'key1':'value1','key2':['value2','value3']}
response = requests.get('http://httpbin.org/get',params=params)
print(response.url)
print(response.content)
#http://httpbin.org/get?key1=value1&key2=value2&key2=value3

1.5 自定义Headers
如果想自定义请求的Headers,同样的将字典数据传递给headers参数
url = ‘http://api.github.com/some/endpoint’
headers = {‘user-agent’:‘my-app/0.0.1’} #自定义headers
response = requests.get(url,headers=headers)

print(response.headers)

1.6 自定义cookies

Requests中自定义cookies也不用再去构造CookieJar对象,直接将字典递给cookies参数

url = ‘http://httpbin.org/cookies’
co = {‘cookies_are’:‘working’}
response = requests.get(url,cookies=co)
print(response.text)   #{“cookies”: {“cookies_are”: “working”}}

1.7 设置代理

#当我们需要使用代理时,同样构造代理字典,传递给proxies参数
import requests
proxies = {
'http':'http://10.10.1.10:3128',
'https':'https://10.10.1.10:1080'
}
requests.get('http://httpbin.org/ip',proxies=proxy)
print(response.text)

2 requests库使用案例

例子1: 采用requests实现百度搜索功能

# -*- coding: utf-8 -*-
__author__ = 'sun'
__date__ = '2019/6/19 14:47'
import requestsdef getfromBaidu(key):#url = 'http://www.baidu.com.cn/s?wd=' + urllib.parse.quote(key) + '&pn='  # word为关键词,pn是分页。kv = {'wd': key}r = requests.get("http://www.baidu.com/s", params=kv)print(r.request.url)with open("baidu.html", "w", encoding='utf8')   as  f:f.write(r.text)key = 'python'
getfromBaidu(key)

例子2:采用get和post方法

# -*- coding: utf-8 -*-
__author__ = 'sun'
__date__ = '2019/6/19 下午9:32'import requests
import  json
r = requests.get(url='http://www.sina.com')  # 最基本的GET请求
print(r.status_code)  # 获取返回状态
r = requests.get(url='http://dict.baidu.com/s', params={'wd': 'python'})  # 带参数的GET请求
print(r.url)
print(r.text)  # 打印解码后的返回数据print("#####################")
payload = (('key1', 'value1'), ('key1', 'value2'))
#urlencode
r = requests.post('http://httpbin.org/post', data=payload)print("code: " + str(r.status_code) + ", text:" + r.text)url = 'http://httpbin.org/post'
files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
r = requests.post(url, files=files)
print(r.text)

2 BeautifulSoup

简介

Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下:

Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。

​ Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。

​ Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。

安装

​ Beautiful Soup 3 目前已经停止开发,推荐在现在的项目中使用Beautiful Soup 4,不过它已经被移植到BS4了,也就是说导入时我们需要 import bs4

进入python虚拟化环境,安装lxml和bs4

​ pip install lxml

​ pip install bs4

使用方法

首先必须要导入 bs4 库

from bs4 import BeautifulSoup

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:

1. Tag
2. NavigableString
3. BeautifulSoup
4. Comment

语法:见附件《Beautiful Soup 4.2.0 文档 — Beautiful Soup.pdf》

例子分析

假设串为:

html_doc = """
<html>
<head><title>The Dormouse's story</title>
</head>
<body>
<p class="title aq"><b>The Dormouse's story</b>
</p>
<p class="story">Once upon a time there were three little sisters; and their names were<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;and they lived at the bottom of a well.
</p>
<p class="story">...</p>
"""

生成soup对象:

soup = BeautifulSoup(html_doc, 'lxml')

(1) Tag

通俗点讲就是 HTML 中的一个个标签,例如

<title>The Dormouse's story</title>
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

上面的 title a 等等 HTML 标签加上里面包括的内容就是 Tag; 下面我们来感受一下怎样用 Beautiful Soup 来方便地获取 Tags

print(soup.title)
# <title>The Dormouse's story</title>print(soup.head)
# <head><title>The Dormouse's story</title></head>print(soup.a)
# <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>print(soup.p)
# <p class="title" name="dromouse"><b>The Dormouse's story</b></p>print type(soup.a)
#<class 'bs4.element.Tag'>

对于 Tag,它有两个重要的属性,是 name 和 attrs

print(soup.name)
print(soup.head.name)
# [document]
# headprint soup.p.attrs
#{'class': ['title'], 'name': 'dromouse'}print soup.p['class']
#['title']print soup.p.get('class')   #等价于上述的
#['title']

可以对这些属性和内容等等进行修改,例如

soup.p['class'] = "newClass"
print(soup.p)
# <p class="newClass" name="dromouse"><b>The Dormouse's story</b></p>

复杂点的操作

# 获取所有文字内容
print(soup.get_text())# 输出第一个  a 标签的所有属性信息
print(soup.a.attrs)for link in soup.find_all('a'):# 获取 link 的  href 属性内容print(link.get('href'))# 对soup.p的子节点进行循环输出
for child in soup.p.children:print(child)# 正则匹配,名字中带有b的标签
for tag in soup.find_all(re.compile("b")):print(tag.name)

(2) NavigableString

既然我们已经得到了标签的内容,那么问题来了,我们要想获取标签内部的文字怎么办呢?很简单,用 .string 即可,例如

print(soup.p.string)
#The Dormouse's story

案例2:

新建文件test.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Hello</title>
</head>
<body><div class="aaa" id="xxx"><p>Hello <span>world</span></p></div><div class="bbb" s="sss">bbbb1</div><div class="ccc">ccc</div><div class="ddd">dddd</div><div class="eeee">eeeee</div>
</body>
</html>

测试python文件如下:

from bs4 import BeautifulSoup
import re
# 1. 创建BeautifulSoup对象
with open("test.html") as f:html_doc = f.read()soup = BeautifulSoup(html_doc, 'lxml')
# 2. 按Tag name 找网页元素
print(f"2.:{soup.title}")
print(f"2.:{soup.title.string}")
# 3. 使用get_text()获取文本
print(f"3.get_text():{soup.div.get_text()}")
# 4. 如何获取属性
print("4.", soup.div['class'])
print("4.get", soup.div.get("class"))
print("4.attrs:", soup.div.attrs)
# 5. find_all(self, name=None, attrs={}, recursive=True, text=None,
#                 limit=None, **kwargs):
# 1) 获取所有符合过滤条件的Tag
# 2) 过滤条件可以是多个条件,也可以是单个条件
# 3)过滤条件支持正则表达式
# 4) 参数说明
# -name- : Tag name, 默认值是None
# -attrs-:字典,字典里可以放tag的多个属性。
# - recursive-:是否递归,默认值是True。
# - text-:按tag里面的文本内容找,也支持正则表达式,默认值是None
# - limit-: 限制找的个数,默认值是None即不限制个数,如果想限制只找前2个的话,
#   设置limit = 2即可。
# -kwargs - : 接受关键参数,可以指定特定的参数。例如: id = '',class_ = ''divs = soup.find_all("div")
for div in divs:print("type(div)", type(div))print(div.get_text())
print(soup.find_all(name='div', class_='bbb'))
print("==", soup.find_all(limit=1, attrs={"class": re.compile('^b')}))
print(soup.find_all(text="bbbb1"))
print(soup.find_all(id="xxxx"))
# 6.find  limit =1 的find_all()
# 7.我们可以像使用find_all一样使用tag.( 按tagname找其实就是find_all的一个快捷方式)
soup.find_all(name='div', class_='bbb')
soup.div(class_='bbb')
# 注意:我们对Tag和BeautifulSoup类型的对象同等对待。
# 8. 查找当前Tag的子节点
# 1) 分多次查找
div_tag = soup.div
print(type(soup))
print(type(div_tag))
print(div_tag.p)
# 2)使用contents获得tag对象的子节点
print("8.2):", soup.div.contents)
# 9. children  返回  list_iterator 类型的对象
body_children = soup.body.children
for child in body_children:print("9. ", child)
# 10. 父节点
tag_p = soup.p
print("10.", tag_p.parent)# 11. 兄弟节点find_next_siblings
# 找当前tag的下面的所有兄弟节点
div_ccc = soup.find(name='div',class_='ccc')
print("11.", div_ccc)
print("11.", div_ccc.find_next_siblings(name='div'))
# 12. 兄弟节点find_previous_siblings
print("12.", div_ccc.find_previous_siblings(name='div'))soup.find_previous_sibling()

作业:
采用requests库爬取百度搜索页面,输入关键字,采用多线程或者多进程方式进行多页爬取

https://www.baidu.com/s?wd=python&pn=20

分页(页数为10页)爬取

转载于:https://www.cnblogs.com/sunBinary/p/11055652.html

安装依赖以及页面解析相关推荐

  1. 开普勒云平台:9个示例解析如何安装依赖

    本文介绍开普勒云平台如何安装依赖. Kplcloud是什么? kplcloud是一个基于Kubernetes的轻量级PaaS平台,通过可视化的界面对应用进行管理,降低应用容器化的对度,从而减少应用容器 ...

  2. android epg界面实现,一种EPG引擎及页面解析方法与流程

    本发明涉及浏览器页面解析领域,更具体的说是涉及一种EPG引擎及页面解析方法. 背景技术: 传统的浏览器客户端当中,需要消耗相当大的资源和文档对象模型接口进行交互,通常是用JS库.参照图1,浏览器解析页 ...

  3. elasticsearch基础6——head插件安装和web页面查询操作使用、ik分词器

    文章目录 一.基本了解 1.1 插件分类 1.2 插件管理命令 二.分析插件 2.1 es中的分析插件 2.1.1 官方核心分析插件 2.1.2 社区提供分析插件 2.2 API扩展插件 三.Head ...

  4. 微信小程序云开发 | 云函数安装依赖

    在小程序中发送http请求有两种方式,第一种是直接在小程序前端页面中发送:第二种是在云函数中发送. 云函数中发送请求不受域名数量的限制,但是需要我们安装依赖才能使用,如got库.这里记录一下在微信小程 ...

  5. Vue安装依赖npm install时报错问题解决方法

    一.用到的一些快捷键: a.打开cmd:   win+R b.进入d盘:d: c.进入d盘某个文件夹:cd myVue d.退回上一级:cd.. 二.Vue安装工作: 1.vue的安装依赖于node. ...

  6. Vue.js-Day06-PM【项目实战(附带 完整项目源码)-day01-pm:轮播组件(使用、安装依赖、具体操作过程)、favicon详细制作】

    Vue.js实训[基础理论(5天)+项目实战(5天)]博客汇总表[详细笔记] 实战项目源码[链接:https://pan.baidu.com/s/1r0Mje3Xnh8x4F1HyG4aQTA   提 ...

  7. 有哪些好用的互联网数据抓取,数据采集,页面解析工具?

    1. 互联网刚兴起的时候,数据索引是个大问题,当时Yahoo的分类页面着实火了一阵子. 2.随着互联网数据量越来越大,Google,百度等搜索引擎火了起来.这个阶段,几乎没有比搜索引擎更火的技术了,连 ...

  8. Java爬虫(二)-- httpClient模拟Http请求+jsoup页面解析

    博客 学院 下载 GitChat TinyMind 论坛 APP 问答 商城 VIP会员 活动 招聘 ITeye 写博客 发Chat 传资源 登录注册 原 Java爬虫(二)-- httpClient ...

  9. 谷歌page speed 安装使用及页面问题详解

    原文地址:http://wenku.baidu.com/view/b0a61f3ebcd126fff7050b40.html 谷歌page speed 安装使用及页面问题详解 谷歌page speed ...

最新文章

  1. 这是马?小鹏发布可骑乘「智能马」,四不像长相太奇葩!
  2. webpage not available是什么意思_MySQL很想啊,为什么还要有noSQL?
  3. 玩转HTML5移动页面
  4. 安卓客户端与服务器交互Json数据
  5. 【django】HttpRequest对象
  6. 借助numpy.rot90实现图片顺时针旋转90°,旋转后图片没有黑边
  7. bzoj 1053: [HAOI2007]反素数ant 51nod-1060:最复杂的数(反素数与因数个数计算)
  8. MySQL初步研究数据库
  9. SQL语句处理一些修改、新增、删除、修改属性操作(MySql)
  10. Python MySQL操作
  11. “/etc/profile“ 无法保存 E212: Can‘t open file for writing
  12. 基于Python实现语义分析
  13. [CM311-1A]-全网最全 Android 软件管理
  14. Android 系统源码以及结构
  15. 最全勒索病毒解密工具
  16. 在线购物系统—类图设计
  17. STM32下移植UCOSIII
  18. lr mysql 增删改查_ssh增删改查流程
  19. HTML5游子吟网页的完整代码,《游子吟》教学案
  20. wamp+php+下载,wampserver 64位(php环境搭建安装包)下载_wampserver 64位(php环境搭建安装包)官方下载-太平洋下载中心...

热门文章

  1. js 去除字符串左右两边的空格
  2. javascript 调用C++函数
  3. Linux——系统开关机指令简单学习笔记
  4. 方法对象Spring MVC SimpleFormController
  5. 排序系列02--选择排序
  6. 判断当前是否运行于Design Mode
  7. Notepad++在编程使用时的小技巧
  8. JS 点击复制Copy
  9. Winform主窗体的设置
  10. vs2019 解决方案加载报错