admin管理员组

文章数量:1531511

urllib的介绍和基本使用基本使用

 1.urllib是什么

        urllib是爬虫常用的一个库,通过他我们能爬取浏览器上的数据,而爬虫则是我们模仿浏览器去爬取数据的一种称号,即将自己假扮成浏览器去拿取数据

=========================================================================

2.urllib的基本使用

#使用urllib获取百度首页的源码
import urllib.request
#(1)定义一个url :你要访问的页面:baidu
url = 'http://www.baidu/?tn=59044660_1_hao_pg&H123Tmp=nunew11'

#(2)模拟浏览器给服务器发送请求
response = urllib.request.urlopen(url)

#(3)获取响应中的页面的源码
#read方法 返回的是字节形式二进制数据
#二进制==》字符串 解码 decode('编码格式')
content = response.read().decode('utf-8')

#(4)打印数据
print(content)

注意:要用http而不是https,

原因:https相较于http的区别:

1、https的端口是443,而http的端口是80,且两者的连接方式不同;

2、http传输是明文的,而https是用ssl进行加密的,https的安全性更高;

3、https是需要申请证书的,而http不需要。 本文操作环境:Windows7系统、Dell G3电脑。

运行结果(截取部分):

=========================================================================

urllib的一个类型和六个方法

 前言: 通过urllib.request()获取的对象是类型是HttpReponse型的,针对这种类型,有六种常见的读取方法

一个类型:HttpResponse

六个方法:

                read():          读取所有字节

                read(n):        读取n个字节

                readline():     读取一行

                readline():     按行读取,并且读取所有行

                getcode():      返回状态码

                getur():           返回url地址

                getheaders():  获取一个状态信息

具体实验代码:

import urllib.request
url = 'https://www.baidu'

#模拟浏览器给服务器发送请求
response = urllib.request.urlopen(url)

#一个类型和六个方法

# print(type(response))
# 读取多少个字节
# content = response.read()
# print(content)
#读取多少个字节
# content = response.read(5)
# print(content)

#读取一行
# content = response.readline()
# print(content)

# content = response.readlines()
# print(content)
#返回状态码
# print(response.getcode())

#返回的url地址
# print(response.geturl())

#获取是一个状态信息
# print(response.getheaders())
# 一个类型:HttpResponse
# 六个方法:read readline readlines getcode geturl getheaders

=========================================================================

urllib下载(urlretrieve())

         前言:接下来到了我最兴奋的下载了(滑稽),通过urlretrieve()下载

这里我们将通过网页,图片和视频的下载,教大家如何下载,但是只适用于那些没有任何没有反爬虫的网站

    方法介绍:urlretrieve(url,filename),其中url是我们获取资源的网址,而filename是我们下载好的资源的名字

        如何获取资源的地址:

        以获取百度的html文件为例子,百度的网页地址是:http://www.baidu

        那么我们就直接使用这个url即可

获取http://www.baidu的html文件:

import urllib.request
#下载网页
url_page = "http://www.baidu"
urllib.request.urlretrieve(url_page,"baidu.html")

下载结果:

 运行HTML文件:

同理我们还可以获取图片资源和视频资源

获取图片资源

1.我们打开百度,搜素你要找的图片,然后按下F12进入编辑者模式,查看图片的src

然后我们将src的地址输入到网站,查看这张图片是否是存在的

 

 然后依葫芦画瓢,将上文中的url改为src的url,file的文件格式又.html改为.jpg 

import urllib.request
# 下载图片
url_image="https://img1.baidu/it/u=2378119578,1413173279&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=508"
urllib.request.urlretrieve(url_image,"周杰伦.jpg")

视频的下载方式同理(下面用一下一个动漫网站)

视频下载

 

然后对src进行测试

 接着将url改为上述的url地址,并将file的格式改为.mp4等视频格式

import urllib.request
#下载地址
url_video = "https://v6.bdxiguavod/9419a4d3395a54752a4e6cb7ff991170/62d6e45e/video/tos/cn/tos-cn-v-3506/00e32bf5691142d287fd4a706947905f/"
urllib.request.urlretrieve(url_video,"hhh.mp4")

 下载时间有点长,就不展示了

=========================================================================

urllib的请求头定制

首先我们需要知道为什么要进行请求头的定制:请求头是最常见的反爬手段,定制请求头是为了应付反爬。

如何再浏览器中找到请求头:

如何再urllib中定制请求头(再这里我们只需要用到请求头中的User-Agent):

import urllib.request

url = "https://www.baidu"

#url的组成
#https://www.baidu/s?wd=周杰伦
#http/https     www.baidu   80/443     s     wd=周杰伦  #
#  协议              主机         端口号     路径   参数      瞄点
#UA反爬
headers ={
   # "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44"
   "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44"
    }
#因为urlopen方法中不能存储字典,所有headers不能直接传递过去
#请求对象的定制
#注意 因为参数顺序的问题,不能直接写url和headers 中间还有一个data 用关键参数传参
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)

content = response.read().decode("utf-8")

print(content)

运行成功

 注意urllib请求头的定制的方法有三个参数:url,data,headers

=========================================================================

urlib的get请求操作

我们平常百度某要东西是都在浏览器里面输入关键字进行搜素,而在urllib中我们同样油类似的方法对我们的爬虫文件进行指定搜素

首先我们想看看浏览器是怎么搜素的:

 所以我们只需要对wd这个参数进行进行传参即可,而在urllib的库里面有一个方法可以完成这一需求,get请求的方法:quote()

import urllib.request
#https://www.baidu/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6

#需求:获取https://www.baidu/s?wd=周杰伦的网页代码
# 寻找url
url = "https://www.baidu/s?wd="
# 第一个反爬UA
headers={
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44'
}
# 编码转换
name=urllib.parse.quote("周杰伦")
# 组装url
url=url+name
# print(url)
# 请求对象的定制
request = urllib.request.Request(url=url, headers=headers)
# 向服务器发请求
response = urllib.request.urlopen(request)
#获取响应信息
content=response.read().decode("utf-8")
# 打印响应信息
print(content)

但我们要爬取多个参数时,urllib的get请求也给我们提供了urlencode()方法

#urlencode应用场景:多个参数的时候

# import urllib.parse
#
# data={
#     'wd' : '周杰伦',
#     'sex': '男'
# }
# urlencode= urllib.parse.urlencode(data)
# print(urlencode)
import urllib.request
import urllib.parse

url ='https://www.baidu/s?'

data={
    'wd' : '周杰伦',
    'sex': '男',
    'location':'中国台湾'
}

new_data = urllib.parse.urlencode(data)
headers={
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44'
}
url=url+new_data
print(url)
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode("utf-8")
print(content)

=========================================================================

urllib的post请求(以百度翻译为例子)

 我们打开百度翻译并用英文输入法输入egg,可以看到,我们输入发egg被输出到sug文件的kw参数上

 因此我们需要对kw参数传参,而这需要用post请求才能完成

import urllib.request
import urllib.parse

url='https://fanyi.baidu/sug'
headers={
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44'
}
data={
    'kw':'spider'
}
#post请求的参数,必须进行编码
data = urllib.parse.urlencode(data).encode("utf-8")
#定制请求对象
request = urllib.request.Request(url=url, data=data, headers=headers)
#向浏览器发送请求
response= urllib.request.urlopen(request)
#获取响应信息
content = response.read().decode("utf-8")

#我们所请求到的参数时json格式,因此要进行json转
#字符串==》json对象
import json
obj = json.loads(content)
print(obj)

#post请求必须编码
#编码之后必须调用encode方法
#参数方正请求对象定制的方法中

========================================================================= 

 urllib的get请求和post请求的区别

1.post请求的参数必须编码+转码,也即编码之后,必须调用encode方法:

data = urllib.parse.urlencode(data).encode('utf-8')

但get请求的参数只需要进行编码即可,也即:

data = urllib.parse.urlencode(data)

2.post请求的参数放在请求对象的定制过程中,而不是拼接字符串:

request = urllib.request.Request(url = url,data = data,headers = headers)
response = urllib.request.urlopen(request)

但get请求的参数使用字符串拼接在url上:

url = base_url + uni_data
request = urllib.request.Request(url = url,headers = headers)
response = urllib.request.urlopen(request)

=========================================================================

urllib的异常处理

直接上代码

import urllib.request
import urllib.error

url = 'http://www.baidu1'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44'
}
try:
    request = urllib.request.Request(url=url, headers=headers)
    responce = urllib.request.urlopen(request)
    content = responce.read().decode("utf-8")
    print(content)
except urllib.error.HTTPError:
    print('系统正在升级')
except urllib.error.URLError:
    print("你输入错误")

第一个错误是HTTPError,这是HTTP请求的错误,我们通过urllib.error.HTTPError这个类型进行匹配,捕捉后对错误进行处理即可

第二个错误是URLError,这是把url书写错误后的错误,我们通过urllib.error.URLError这个类型进行匹配,捕捉后同样处理错误。

=========================================================================

urllib的handler处理器

什么时handler处理器:

handler处理器是urllib库中继urlopen()方法之后又一种模拟浏览器向服务器发起请求的方法或技术。

它的意义在于使用handler处理器,能够携带代理ip,这为对抗反爬机制提供了一种策略(很多的网站会封掉短时间多次访问的ip地址)。

下面是handler处理器的具体使用方法,其中不含代理ip的部分,代理ip这部分将在下一篇笔记中介绍。

import urllib.request

url="https://www.baidu/s?word=ip"

headers={
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44'
}

request=urllib.request.Request(url=url,headers=headers)

# 1.获取handler对象
handler=urllib.request.HTTPHandler()
# 2.=获取opener对象
opener=urllib.request.build_opener(handler)
# 3.调用open方法
response=opener.open(request)
content=response.read().decode("utf-8")
print(content)

代码的步骤很清晰,我们可以简化整个过程为三个步骤:首先通过urllib库新建一个handler对象,而后通过urllib库的build_opener()方法新建一个opener对象,其中build_opener()要传入handler对象,最后通过opener的open()方法,获取响应,传参是我们的request定制请求对象。

=========================================================================

urllib的代理IP

什么是代理IP

代理IP地址一般是说代理服务器的IP地址,就是说你的电脑先连接到代理IP,然后通过代理服务器上网,网页的内容 通过代理服务器,传回你自己的电脑。代理IP就是一个安全保障,这样一来暴露在公网的就是代理IP而不是你的IP了!

 为什么需要代理IP

我们通过代理ip能够防止自己的ip在爬取内容的时候暴露,这样一方面提高了保密性,最重要的点是通过代理ip,我们可以应对ip被封这一反爬机制了!

代理IP在哪里可以获取

国内高匿免费HTTP代理IP - 快代理

如何使用urllib的代理ip功能

import urllib.request

url="https://www.baidu/s?word=ip"
headers={
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36 Edg/103.0.1264.49'
}

#编写IP地址
proxies={
    'http':'202.55.5.209:8090'
}

request=urllib.request.Request(url=url,headers=headers)
# handler build_opener open
# response=urllib.request.urlopen(request)
# 通过handler处理器传入ip地址
handler=urllib.request.ProxyHandler(proxies=proxies)

opener=urllib.request.build_opener(handler)

response=opener.open(request)
content=response.read().decode("utf-8")

with open('daili.html','w',encoding='utf-8')as fp:
    fp.write(content)

=========================================================================

urllib的代理池

什么是代理池

所谓代理池,就是很多的ip在一起的一个结构,在这个结构里,我们能够在每一次请求中使用不同的ip地址,从而减少同一个ip的使用频率,以降低ip被封掉的风险,对抗反爬机制!

如何实现代理池

import urllib.request

url="https://www.baidu/s?word=ip"
headers={
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36 Edg/103.0.1264.49'
}
import random
# 建立多个代理
proxies=[
    {'http':'202.55.5.209:8090'},
    {'http':'47.56.69.11:8000'},
    {'http':'112.14.47.6:52024'}
]
# 通过随机选择来使用某个代理
proxies=random.choice(proxies)

request=urllib.request.Request(url=url,headers=headers)

handler=urllib.request.ProxyHandler(proxies)
opener=urllib.request.build_opener(handler)
open=opener.open(request)

content=open.read().decode("utf-8")
print(content)
# with open('daili.html','w',encoding='utf-8')as fp:
#     fp.write(content)

=========================================================================

Xpath的使用

下载xpath库

pip install lxml==4.6.2 -i http://pypi.douban/simple/ --trusted-host pypi.douban

如果下载失败,可以看看你的vpn有没有关闭,没有关闭可能会导致下载失败

使用了谷歌浏览器的控制程序增加xpath插件

下载xpath的zip文件

 链接:https://pan.baidu/s/1-e-NAcjTi7yuVp7TU0wStA 
提取码:rh1z

无需解压,直接拖入到控制程序页面中,xpth插件就会自动安装到浏览器上了

什么时xpath

xpath是一种筛选html或者xml页面元素的【语法】

使用Xpath解析本地文件

html文件名字定为xxx.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
<ul>
    <li id="l1">北京</li>
    <li id="l2" class="i11">上海</li>
    <li >深圳</li>
    <li >武汉</li>
</ul>
<!--<ul>-->
<!--    <li>大连</li>-->
<!--    <li>景州</li>-->
<!--    <li>沈阳</li>-->
<!--</ul>-->
</body>
</html>
#导入lxml库
from lxml import etree

#xpath解析
# 1.本地文件        extree.parse
# 2.服务器响应的数据 extree.html
# 解析本地文件
tree=etree.parse('070_尚硅谷_urllib_xpath的基本使用.html')
# 查找ul下面的li
# li_list=tree.xpath('//ul/li')

# 查找带有id的li
# li_list =tree.xpath('//ul/li[@id]/text()')

# 查找带有id=l1的li
# li_list =tree.xpath('//ul/li[@id="l1"]/text()')
# 查找带有id=l1的li且带有class属性值的li
li_list =tree.xpath('//ul/li[@id]/@class')
# 判断列表的长度+
print(li_list)
print(len(li_list))

使用xpath插件获取百度一下

import urllib.request

url="https://www.baidu/"
headers={
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44'
}
request=urllib.request.Request(url=url,headers=headers)
response=urllib.request.urlopen(request)
content=response.read().decode("utf-8")
# print(content)

from lxml import etree
# 解析服务器响应的文件
tree=etree.HTML(content)
# 获取想要的文件
result=tree.xpath('//input[@id="su"]/@value')

print(result)

=========================================================================

jsonpath的使用

jsonpath是什么:

jsonpath是一种简单的方法来提取给定JSON文档的部分内容。

为什么要学习jsonpath:

因为有时候我们拿到的数据是以json为格式的数据,此时我们不再能够使用之前学习的xpath对内容进行解析,因此我们需要一种方法来解析json格式的数据,它就是jsonpath

jsonpath的安装

pip install jsonpath -i http://pypi.douban/simple/ --trusted-host pypi.douban

jsonpath的基本使用:

强调:就jsonpath只能处理本地的json文件,不能直接处理服务器的响应

首先编写一个json文件(文件名命名为jsonpath.json)

{"store":{
  "book": [
    {"category":"修道",
      "author": "六道",
      "title": "坏蛋是怎样练成的",
      "price": 8.95
    },
    {"category":"修改",
      "author": "天蚕土豆",
      "title": "斗破苍穹",
      "price": 12.99
    },
    {"category":"修真",
      "author": "唐家三少",
      "title": "斗罗大陆",
      "jsbn": "0-0",
      "price": 8.99
    }
  ],
  "bicycle": {
    "author": "天蚕土豆",
    "color": "黑色",
    "price": 12
  }
}}

然后我们在进行jsonpath的基本使用

jsonpath与xpath的语法表格

XPathJSONPath描述
/$根元素
.@当前元素
/. or []当前元素的子元素
..n/a当前元素的父元素
//..当前元素的子孙元素
**通配符
@n/a属性的访问字符

jsonpath的代码

# 导入库
import jsonpath
import json

# 打开json文件,编码格式为utf-8
#这里要注意,我们调用函数之前,要先导入json库和jsonpath库;此外,我们通过json.load()函数导入我#们的json文件,这个函数的传参不是文件名,而是一个文件对象。
#这里多解释一下,也就是说,我们传参是:json.load(文件对象),而不是json.load('store.json'),后#者是一个字符串,会报错,至于这个文件对象,我们可以直接用open()函数创建,也可以在外面先用open函#数新建一个文件对象,之后将对象传入,二者均可。

obj=json.load(open('jsonpath.path','r',encoding='utf-8'))
#第一行的/是根元素的意思,也就是说在jsonpath中,每一句jsonpath语言都要以一个$符号开头,后面的 #部分按照上面与xpath对照进行理解即可。(n/a表示该项不存在)
# 书店所有书的作者
# authou_list=jsonpath.jsonpath(obj,'$.store.book[0].author')
# print(authou_list)

# 所有的作者
# authou_list=jsonpath.jsonpath(obj,'$..author')
# print(authou_list)

# store下面的所有元素
# authou_list=jsonpath.jsonpath(obj,'$.store.*')
# print(authou_list)

# store下面的所有的钱
# authou_list=jsonpath.jsonpath(obj,'$.store..price')
# print(authou_list)

#第三本书
# book=jsonpath.jsonpath(obj,'$..book[2]')
# print(book)

# 最后一本书
# book=jsonpath.jsonpath(obj,'$..book[(@.length-1)]')
# print(book)

# 前两本书
# book=jsonpath.jsonpath(obj,'$..book[0,1]')
# book=jsonpath.jsonpath(obj,'$..book[:2]')
# print(book)

# 过滤出所有带有jsbn的书
# book=jsonpath.jsonpath(obj,'$..book[?(@.jsbn)]')
# print(book)

# 过滤出价格低于10的书
# book=jsonpath.jsonpath(obj,'$..book[?(@.price>10)]')
# print(book)

# 所有的元素
allElements=jsonpath.jsonpath(obj,'$..')
print(allElements)

========================================================================= 

bs4的使用

bs4的介绍:

BS4全称是Beatiful Soup,它提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能,解析的对象是本地html文件和服务器的响应html文件

bs4的安装:

pip install bs4 -i http://pypi.douban/simple/ --trusted-host pypi.douban

bs4解析本地文件(将html和python文件放在同一目录下):

创建本地html文件取名为bs4.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <ul>
        <li id="1">张桑</li>
        <li id="2">李桑</li>
        <li id="3">王桑</li>
        <a id="4" href="" class="a1">敬礼敬礼</a>
        <span>1</span>
    </ul>
</div>

        <a href="" title="a2">敬礼敬礼</a>
        <div id="d1">
            <span>
                哈哈哈
            </span>
        </div>
<p id="p1" class="p1">hhh</p>
</body>
</html>

bs4解析HTML文件:

from bs4 import BeautifulSoup

# 通过解析本地文件将bs4的基础语法进行讲解
# 默认打开的文件的编码格式是gbk 所以打开文件是要指定默认编码
soup = BeautifulSoup(open('bs4.html',encoding='utf-8'),'lxml')

# print(soup)
# 1.find
# print(soup.findAll)
# 返回第一个符合条件的数据
# print(soup.find('a'))
# 根据title的值找到对应的标签对象
# print(soup.find('a',title='a2'))
# 根据class的值找到对应的标签对象
# print(soup.find('a',class_="a1"))

# 2.find_all
# 返回一个列表,并且返回所有的a标签
# print(soup.find_all('a'))
# rg想获取的是多个标签的数据,那么需要在find_all的参数中添加的是列表的数据
# print(soup.find_all(['a','span']))
# limit的作用是查找前几个数据
# print(soup.find_all('li',limit=2))
# 3.select(推荐x`)
#select方法返回的是一个列表,并且返回多个数据
# print(soup.select('a'))
# 可以通过.代表class 我们把这种叫做类选择器
# print(soup.select('.a1'))

# 属性选择器
# 查找li标签中带有id的标签
# print(soup.select('li[id]'))

# 查到li标签中id为2的标签
# print(soup.select('li[id="2"]'))


# 层级选择器
#  后代选择器
# 找到div下面的li
# print(soup.select('div li'))

# 子代选择器
#  某标签的第一子标签
#注意:在好多的计算机语言中 如果不加空格会出现不输出内容的错误 但是在bs4中不会出现这种错误
# print(soup.select('div>ul>li'))

#节点信息
#   获取节点内容
# obj=soup.select('#d1')[0]
# 如果标签对象中 只有内容 那么string和get_text()都可以使用
# 如果标签对象中 除了内容还有标签 那么string就获取不到数据 而get_text()是可以获取数据
# 我们一般情况下 推荐使用get_text()
# print(obj.string)
# print(obj.get_text())

# 节点的属性
# ogj=soup.select('#p1')[0]
# neme是标签的名字
# print(ogj.name)
# 将属性值左右作为一个字典返回
# print(ogj.attrs)

# 获取节点的属性
ogj=soup.select('#p1')[0]

# print(ogj.attrs.get('class'))
# print(ogj.get('class'))
print(ogj['class'])

bs4处理响应式文件

from bs4 import BeautifulSoup
 
soup = BeautifulSoup(content,'lxml')

服务器的响应应当用上述的格式进行书写:使用Beautifulsoup()函数,传入两个参数,第一个参数是服务器的响应的内容第二个参数是'lxml’这个固定的参数

=========================================================================

selenium库的使用:

什么是selenium库:

selenium是一个自动化测试工具,支持Firefox,Chrome等众多浏览器 在爬虫中的应用主要是用来解决JS渲染的问题。

为什么要用selenium库

爬虫,selenium能够模拟真人打开浏览器,因此可以更好的获取我们需要的数据。(有时候,使用urllib库模拟浏览器的时候,会被服务器识别,返回的数据有所缺失,因此我们的确需要selenium做爬虫)

自动化小工具,例如可以帮我们操作一些浏览器的交互等等(释放双手)。

安装selenium库

pip install selenium==3.4 -i http://pypi.douban/simple/ --trusted-host pypi.douban

安装模拟真人操作浏览器的浏览器工具

谷歌浏览器工具下载

首先我们需要了解我们的谷歌浏览器的版本号

 

 然后下载对应的版本

 不用一一对应,只需要前几位数差不多就可以,下载完成后放入python同级目录下

 selenium库的基本使用

打开京东商城

# 1.导入selenium
from selenium import webdriver

# 创建浏览器操作对象
path='chromedriver.exe'

browser = webdriver.Chrome(path)

# 3.访问网站
# url='https://www.baidu'
# browser.get(url)
url='https://www.jd/'
browser.get(url)
#获取网页源码
content=browser.page_source
print(content)

导入selenium库,初始化了浏览器操作对象。导入时格式是 from selenium import webdriver,导入后,我们可以创建一个字符串变量path,path的值是我们之前安装浏览器工具的路径,如果安装在与此python文件同级目录下,则直接输入其名称即可,否则要使用绝对路径!

最后用webdriver.Chrome()函数,传入路径,创建一个浏览器操作对象browser(名字可以自定义),

定义需要打开的网页的地址,之后使用get()函数,模拟真人打开浏览器并传入url,与此同时,我们的browser对象也与这个url建立了绑定,后续获取源码或者节点的信息都需要通过这个browser对象。最后,通过page_source函数,获取当前url的网页的源码

元素定位

from selenium import webdriver
from selenium.webdrivermon.by import By

path='chromedriver.exe'
browser=webdriver.Chrome(path)

url='https://www.baidu'
browser.get(url)

content = browser.page_source
# print(content)
#元素控制

# (1) 根据id属性的属性值找到对象_重要:
button=browser.find_element(By.ID, 'su')
print(button)

# (2) 根据name属性的属性值找到对象:

button = browser.find_element(By.NAME,'wd')

print(button)

# (3) 根据xpath的语句找到对象_重要:

button = browser.find_element(By.XPATH,'//input[@id = "su"]')

print(button)

# (4) 根据标签的名称找到对象

button = browser.find_element(By.TAG_NAME,'input')

print(button)

# (5) 根据CSS选择器找到对象,相当于bs4的语法_重要:

button = browser.find_element(By.CSS_SELECTOR,'#su')

# (6) 根据链接元素查找对象:

button = browser.find_element(By.LINK_TEXT,'新闻')

所谓的定位元素,就是指我们通过一些方法把页面上的元素与实际的代码中的对象(变量)进行绑定,以便于后续通过操作这些对象来获取元素信息、实际控制或操作页面上的元素(如果学过前端js、安卓的朋友可能比较理解这样的模式)。这些上面展示了六种定位元素的办法,其中比较重要的是前三种和第五种,即id、name、xpath语句、CSS选择器这四种方式,其他两种仅作为了解即可。

元素信息的获取:

from selenium import webdriver
from selenium.webdrivermon.by import By

path='chromedriver.exe'
browser=webdriver.Chrome(path)

url='https://www.baidu'
browser.get(url)

#元素信息以及交互

# 根据id来找到对象
input=browser.find_element(By.ID, 'su')

# (1) get_attribute()函数获取标签的指定属性的属性值
# 传参是属性的名称,例如class、id等,返回这些属性的属性值

print(input.get_attribute('class'))

# (2) tag_name函数获取元素对应的标签的名称,例如元素是input标签,返回值就是input

print(input.tag_name)

# (3) text函数获取标签的文本,文本指的是标签尖括号的内容:
# 例如:<div> xxx </div> 于是获取的结果是xxx

print(input.text)

 定位到id值是su的input表单元素之后,我们把这个元素与变量input进行绑定,而后通过操作input,我们能够获取关于这个表单元素的信息,其中重要的信息有两个:一个是元素的属性值,则可以通过get_attribute()函数获取,这个函数的传参是属性的名称,比如class、id等等,返回的是该属性的属性值;另一个是标签内的文本,这可以通过text属性获取。

交互

import time

from selenium import webdriver
from selenium.webdrivermon.by import By

path='chromedriver.exe'

browser=webdriver.Chrome(path)

url='https://www.baidu'
browser.get(url)
time.sleep(2)
# 获取文本对象
input=browser.find_element(By.ID,'kw')
# 在文本框输入周杰伦
input.send_keys('周杰伦')

time.sleep(2)

# 获取按钮对象
button=browser.find_element(By.ID,'su')
# 点击按钮
button.click()
time.sleep(2)

# 滑到底部
js_bottom='document.documentElement.scrollTop=100000'
browser.execute_script(js_bottom)

time.sleep(2)

# 获取下一页
next=browser.find_element(By.XPATH,'//a[@class="n"]')
next.click()

# 回到上一页
browser.back()

time.sleep(2)

# 回去
browser.forward()

time.sleep(2)

# 退出
browser.quit()

=========================================================================

selenium无界面浏览器的学习

为什么要学习无界面浏览器:

之前学的selenium库,是真实打开了浏览器,但是优缺点:速度很慢,有时候我们需要更高速的获得数据或其他事情,因此我们需要了解两种无界面浏览器的操作:

phantomjs的基本使用:

下载连接 提取码:ysbd

下载完成后放入同级的文件下

最后,导入phantomjs并创建浏览器操作对象

from selenium import webdriver
from selenium.webdrivermon.by import By
path='phantomjs.exe'
browser=webdriver.Phantomjs(path)

后续操做和selenium的操作一毛一样

handless的基本使用

首先创建浏览器操作对象(进行封装)

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def handless_browser():
    chrome_options = Options()

    chrome_options.add_argument('--headless')

    chrome_options.add_argument('--disable-gpu')

    # path这里要改成自己的谷歌浏览器的路径:

    path = r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'

    chrome_options.binary_location = path

    browser = webdriver.Chrome(chrome_options=chrome_options)

    return browser
browser = handless_browser()
url='https://www.baidu'
browser.get(url)

=========================================================================

Requests库的学习

什么是Requests库:

它是一个Python第三方库,处理URL资源特别方便,可以完全取代之前学习的urllib库,并且更加精简代码量(相较于urllib库)。

Requests库的安装:

pip install bs4 -i http://pypi.douban/simple/ --trusted-host pypi.douban

Requests的基本使用:

首先我们先想想用urllib的向服务器发起请求的步骤,首先是导入库,然后创建url对象,接着通过urllib.request.urlopen()向服务器发起请求,同理Requests的步骤也是这样子

import requests

url='http://www.baidu'

response=requests.get(url)

 导入requests库,创建url,使用response接受服务器的响应

Requests的一个类型和六个方法:

import requests

url='http://www.baidu'

response=requests.get(url)
# print(type(response))
# 一个类型和六个属性
# Response类型

#设置响应的编码格式
# response.encoding='utf-8'
# 以字符串的形式返回网页源代码
# print(response.text)
# 返回一个url地址
print(response.url)
# 返回二进制的数据
print(response.content)
# 返回相应的状态码
print(response.status_code)
# 返回响应头
print(response.headers)

Requests的get请求:

requests的get请求与urllib的请求方式有些许不同,那就是没有请求对象的定制

import requests

url='https://www.baidu/s?'
headers={
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44'
}
data={
    'wd':'北京'
}

# url:请求路径
# params:参数
# kwargs:字典
response=requests.get(url=url,params=data,headers=headers)

print(response.text)

总结:
1.参数使用params进行传递
2.参数无需urlencode编码
3.不需要请求对象的定制
4.请求资源路径的?可以加也可以不加

Requests库的Post请求

requests的post请求与urllib的请求方式也有不同,不仅没有请求对象的定制而且也没有参数的编码和转码的操作

import requests

url='https://fanyi.baidu/sug'

headers={
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44'
}

data={
    'wd':'北京'
}
# url:请求路径的地址
# data:请求参数
# kwargs:字典
response=requests.post(url=url,data=data,headers=headers)
content=response.text

import json
obj=json.loads(content,encoding="utf-8")
print(obj)

总结:
1.post请求不需要编解码
2.post请求的参数是data
3.不需要请求对象的定制

Requsets的代理IP:

回忆urllib库代理ip,我们需要创建handler处理器,还要定义opener对象,但requests库中,我们只需要把代理ip作为一个普通的参数,传入requests.get()/requests.post()函数即可(简直太方便了!)

import requests


url='https://www.baidu/s?word=IP'

headers={
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44'
}

data={
    'wd':'北京'
}
proxies={
    'http':'202.55.5.209:8090'
}
response=requests.get(url=url,headers=headers,proxies=proxies)
content=response.text
print(content)

总结一下resquests库与urllib库的区别:

1.resquests库是一个特征六个属性,urllib是一个特征六个方法

2.requests库的get和post请求不需要请求对象的定制,而urllib需要

3.requests库的代理ip是直接传入的,代理ip作为一个参数传入,而urllib不经需要使用handler还要创建opener对象

=========================================================================

scrapy框架的基本使用

什么是Scrapy框架

Scrapy是适用于Python的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试

scrapy框架的工作原理:

spiders

spiders可以理解为代表了我们人的操作,我们在操作scrapy的时候,实际上就是以spiders的身份在操作,初始的url是我们定义的。

引擎

引擎是scrapy框架的中枢,从图中可以看出,引擎与所有的其他组件交互,并且交互大多带有指令性的操作,可以理解成一个指挥官。

调度器

调度器,顾名思义,它是用来做调度的,简单的说就是它会把所有请求的url放入一个队列中,每一次会从队列中取出一个url,这个过程叫做调度。

下载器

下载器,是用来下载数据的,它下载的是原始数据,可以理解为网页源码,这些源数据通过引擎再次交给我们用户spiders做进一步解析处理。(下载器沟通因特网,数据来源也是因特网)

管道

管道的工作是下载图片、文件,它的工作与调度器下载源数据不同,它下载的是经过解析后的具体的图片、文件等数据。

用一句话来描述scrapy框架的工作过程

首先,spiders想要在某个url对应的网页下下载图片,于是spiders向引擎递交url,之后引擎把url放入调度器排队;当这个url排到队首的时候,调度器取出这个url请求,交给引擎;这时候引擎把请求给下载器,下载器访问因特网,拿到源数据,交给引擎;引擎再把源数据给spiders。经过这一波操作,源数据被spiders拿到。之后spiders解析数据,并把里面的url和需要下载的数据分离,并一起交给引擎,引擎把url和需下载的数据分别交给调度器和管道,调度器继续重复上述操作,管道下载文件。

安装scrapy框架

pip install scrapy -i https://pypi.douban/simple

如何创建scrapy文件

1.win+r输入cmd,创建爬虫的项目

2.打开spider文件,并创建要爬取的网页的文件

 3.创建好的的文件的项目结构

Spiders文件夹:这文件夹我们不陌生,因为每一次新建scrapy爬虫项目后,我们都需要终端进入Spiders文件夹,生产爬虫文件。在Spiders文件夹下,又有两个文件,一个是_init_.py文件,一个是baidu.py。_init_.py文件是我们创建项目时默认生成的一个py文件,我们用不到这个py文件,因此我们可以忽略它,另一个baidu.py文件是我们爬虫的核心文件,后续的大部分代码都会写入这个文件,因此它是至关重要的py文件。

_init_.py文件:它和上面提到的Spiders文件夹下的_init_.py一样,都是不被使用的py文件,无需理会。

items.py文件:这文件定义了数据结构,这里的数据结构与算法中的数据结构不同,它指的是爬虫目标数据的数据组成结构,例如我们需要获取目标网页的图片和图片的名称,那么此时我们的数据组成结构就定义为 图片、图片名称。后续会专门安排对scrapy框架定义数据结构的学习。

middleware.py文件:这py文件包含了scrapy项目的一些中间构件,例如代理、请求方式、执行等等,它对于项目来说是重要的,但对于我们爬虫基础学习来说,可以暂时不考虑更改它的内容。

pipelines.py文件:这是我们之前在工作原理中提到的scrapy框架中的管道文件管道的作用是执行一些文件的下载,例如图片等,后续会安排对scrapy框架管道的学习,那时会专门研究这个py文件。

settings.py文件:这文件是整个scrapy项目的配置文件,里面是很多参数的设置,我们会偶尔设计到修改该文件中的部分参数,例如下一部分提到的ROBOTS协议限制,就需要进入该文件解除该限制,否则将无法实现爬取。

4.然后我们输入scrapy crawl baidu运行spiders下的baidu.py

=========================================================================

robots协议:

什么是robots协议:

robots协议也叫robots.txt,是一种存放于网站根目录下的ASCII编码的文本文件,它通常告诉网络搜索引擎的漫游器(又称网络蜘蛛),此网站中的哪些内容是不应被搜索引擎的漫游器获取的,哪些是可以被漫游器获取的。也被称为君子协议

打开settings.py文件,把 ROBOTSTXT_OBEY = True 这句代码''解除''注释:

 在使用scrapy框架的时候,我们在拿不到数据时,可以考虑是否是robots协议起到了作用,如果是这样,那就把 ROBOTSTXT_OBEY = True 这句代码注释即可

=========================================================================

scrapy框架的基本语法介绍

打开spider项目下的baidu.py

 name='baidu'就相当于我们启动爬虫的名命对象,也就是中的baidu

response的值,而这个response的值就是服务器给我们的响应。针对这个response响应,有下面的基础操作:

    def parse(self, response):
        # (1) response.text属性:获取的是字符串形式的数据
        content_str = response.text
        print(content_str)
        # (2) response.body属性:获取的是二进制形式的数据
        content_b = response.body
        print("====================")
        print(content_b)
        # (3) response.xpath()函数可以直接使用xpath解析
        # (4) response.extract() 提取selector对象的属性值
        # (5) response.extract_first() 提取selector列表的第一个数据
        pass
  1. response.xpath(xpath语句传入):这种方式是对response进行xpath解析,我们在括号内传入xpath语法对应的语句即可,要注意的是,普通的xpath解析,返回的是一个列表,但是在scrapy框架中的xpath解析,返回的是selector对象列表,针对selector对象列表,我们需要进一步的处理,才能真正拿到数据。
  2.  response.extract():这种处理,承接了上面的操作,当我们拿到了selector对象列表,通过再执行.extract()函数,即可把selector对象列表转成普通的列表,进而获取数据。
  3.  response.extract_first():这是第二种方法的加强版本,可以直接拿到转成的普通列表的第一个元素,在一些情况下更方便。

本文标签: 爬虫学习笔记