python爬虫

爬虫核心

  • 步骤:
    • 爬取整个网页
    • 解析数据,解析网页数据,得到想要的数据
  • 难点:
    • 爬虫和反爬虫

反爬手段

  • user-angent
    • 服务器可以识别客户端的操作系统、cpu、浏览器版本等
    • 通过这个数据,服务器识别客户端是机器还是人
  • 代理ip
    • 判断是否存在异于人类的行为(比如每秒点击次数过多),这个时候服务器就会把客户端的ip封了
  • 验证码访问
  • 动态加载网页
    • 网页返回js数据,并非真实数据
  • 数据加密

爬虫常用库

urllib

  • 功能:
    • 模拟浏览器向服务器发送请求

基本用法

  • 用法:
    • # 使用urllib获取百度首页源码
      import urllib.request
      
      # 定义一个url
      url = 'http://www.baidu.com'
      
      # 模拟浏览器向服务器发送请求 response 响应
      response = urllib.request.urlopen(url)
      
      # 获取响应中的页面源码
      # read 方法返回的是字节形式的二进制数据,需要将二进制形式转化为字符串,即解码decode('编码格式')
      content = response.read()
      
      # 打印数据
      print(content)
      

      这次执行之后得到的数据如下

    • 我们发现得到的百度网盘的源码最前面写着b,并且源码中并未出现像“百度”这样的中文,这是因为read()函数返回的是二进制形式的内容,需要加decode来解码

    • decode(‘编码类型’)中编码类型的确定方法:

      • 打开百度搜索网页源码, 找到charset

      • 后面的内容就是编码类型 

  • 修改之后的代码如下:
    •  
      # 使用urllib获取百度首页源码
      import urllib.request
      
      # 定义一个url
      url = 'http://www.baidu.com'
      
      # 模拟浏览器向服务器发送请求 response 响应
      response = urllib.request.urlopen(url)
      
      # 获取响应中的页面源码
      # read 方法返回的是字节形式的二进制数据,需要将二进制形式转化为字符串,即解码decode('编码格式')
      content = response.read().decode('utf-8')
      
      # 打印数据
      print(content)
      

       此时就能得到正常的网页源码了。

urllib中的read、readline、readlines以及get方法等

    • import urllib.request
      
      url = 'http://www.baidu.com'
      
      #模拟服务器发送请求
      response = urllib.request.urlopen(url)
      
      # 一个类型和六个方法
      # response 是httpresponse类型
      print(type(response))
      
      # read方法按字节读取,读取速度较慢
      # content = response.read()
      #print(content)
      
      # read中的参数表示只读n个字节
      # content = response.read(5)
      # print(content)
      
      # 只能读取一行
      # content = response.readline()
      # print(content)
      
      # 读取所有行,每次读一行,速度较快
      # content = response.readlines()
      # print(content)
      
      # 返回状态码,如果是200,则证明获取网页成功
      print(response.getcode())
      
      # 返回url地址
      print(response.geturl())
      
      # headers中的状态信息
      print(response.getheaders())
      
      # 一个类型  HTTPResponse
      # 六个方法 read readline readlines getcode geturl getheaders

urllib下载

import urllib.request

# 下载网页
url_page = 'http://www.baidu.com'

# url 下载路径
# filename 文件名
urllib.request.urlretrieve(url_page, 'baidu.html')

# 下载图片
url_img = 'https://img2.baidu.com/it/u=331121307,2721562722&fm=253&fmt=auto&app=138&f=JPEG?w=561&h=500'
urllib.request.urlretrieve(url_img, 'lisa.JPEG')

# 下载视频
url_video = 'https://vd4.bdstatic.com/mda-nanqpmhz0dr117g2/720p/h264_delogo/1642958778335147109/mda-nanqpmhz0dr117g2.mp4?v_from_s=hkapp-haokan-nanjing&auth_key=1643037477-0-0-68fb4cfd705f21ff3e5482ff469aeda7&bcevod_channel=searchbox_feed&pd=1&pt=3&logid=2877641603&vid=9060722192467841255&abtest=3000212_5&klogid=2877641603'
urllib.request.urlretrieve(url_video, 'xinwen.mp4')

其中网页链接的获取方式为:

删掉之后的内容就是代码中用到的内容 

  

图片链接的获取方式为:

视频链接的获取方式为:

user agent(ua)反爬措施(请求定制对象)

在爬取百度首页的网页源码时,输入http://www.baidu.com可以得到完整源码,输入https://www.baidu.com得到的是不完整的源码,这就是user agent反爬措施,服务器可以知道客户端的浏览器版本、cpu大小等信息。

import urllib.request

url = 'https://www.baidu.com'

# url 的组成

# https://www.baidu.com/s?wd=周杰伦

# 协议                 主机             端口号         路径      参数          锚点
# http/https        www.bidu.com        80/443         s        wd=周杰伦
# http 80
# https 443
# mysql 3306
# oracle 1521
# redis 6379
# mongodb 27017

response = urllib.request.urlopen(url)
content = response.read().decode('utf-8')
print(content)

查看网页ua的方法:

首先打开网页,然后右键-检查(inspect)(或者直接点击fn+f12)

 点击network - f5刷新 - 点击www.baidu.com - 查看headers中最后一部分 - 查看user agent

那么在爬取的时候只需要传入ua参数就可以爬取内容了

import urllib.request

url = 'https://www.baidu.com'

# url 的组成

# https://www.baidu.com/s?wd=周杰伦

# 协议                 主机             端口号         路径      参数          锚点
# http/https        www.bidu.com        80/443         s        wd=周杰伦
# http 80
# https 443
# mysql 3306
# oracle 1521
# redis 6379
# mongodb 27017

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

# urlopen方法中不能传入字典
# 请求对象的定制
# Request里面的参数是url = url headers = headers 的原因是Requese的参数是url data headers所以这里的传参要特别说明
request = urllib.request.Request(url=url, headers=headers)

response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)

get请求的quote方法

首先看下面这段代码


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

# 需求 获取网页源码

import urllib.request

url = 'https://www.baidu.com/s?wd=周杰伦'

# 请求对象定制,解决ua
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36'
}

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

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

# 获取响应的内容
content = response.read().decode('utf-8')

# 打印数据
print(content)

这段代码会直接报错,可以看到这段代码和前面那段代码唯一的区别就是url中wd=后面的内容,这段代码用了unicode码,而上一段用了ASCII码。实际上url中用的解码方式是ASCII码,所以这段报了错,那么如何解决这个问题哪?

答案就是quote方法,其可以将汉字转化为unicode编码

修改之后的代码如下


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

# 需求 获取网页源码

import urllib.request
import urllib.parse

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

# 请求对象定制,解决ua
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36'
}

# 将周杰伦编程unicode编码格式
name = urllib.parse.quote('周杰伦')
print(name)
print(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)

get方法的urlencode方法

上面的quote方法在传入参数有多个的时候是比较麻烦的,需要进行多次拼接。解决方法是:

# urlencode 用于多参数场景

import urllib.request
import urllib.parse

# https://www.baidu.com/s?wd=周杰伦&sex=男

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

a = urllib.parse.urlencode(data)
print(a)

上面这段代码的输出为:

 完整代码如下:

# urlencode 用于多参数场景

import urllib.request
import urllib.parse

# https://www.baidu.com/s?wd=周杰伦&sex=男

base_url = 'https://www.baidu.com/s?'

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

new_data = urllib.parse.urlencode(data)

# 请求资源路径
url = base_url + new_data

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

# 请求对象的定制
request = urllib.request.Request(url=url, headers = headers)

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

# 获取网页源码的数据
content = response.read().decode('utf-8')

print(content)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值