一:什么是爬虫

网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,经常被称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

即打开一个网页,里面有网页内容吧,想象一下,有个工具,可以把网页上的内容获取下来,存到你想要的地方,这个工具就是我们今天的主角:爬虫

二:requests介绍

1:requests介绍

requests 是 Python 中的一个 HTTP 库,可以用于发送 HTTP/1.1 请求。它可以让 Python 发送 HTTP/1.1 请求,包括 GET、POST、PUT、DELETE、HEAD、OPTIONS 等方法,同时也支持 cookie、header、SSL 等特性。

2:安装requests

pip install requests

3:requests使用

(1):GET请求

import requests  #导入 Requests 模块
params= {'key1': 'value1', 'key2': 'value2'}
r = requests.get("https://XXX", params=params)

(2):POST请求

import requests  #导入 Requests 模块
data = {'key1': 'value1', 'key2': 'value2'}
r = requests.post("https://XXX", data=data)

(3):其他请求

r = requests.put("https://XXX")    #put请求 
r = requests.delete("https://XXX")  #delete请求 
r = requests.head("https://XXX")      #head请求 
r = requests.options("https://XXX")   #options请求

(4):requests响应

  1. 字符串内容响应
import requests   #导入 Requests 模块
import ast

r = requests.get('https://XXX')   #像目标url地址发送get请求,返回一个response对象
content = r.text   #获取响应内容
# #将字符串转字典型
content_list = ast.literal_eval(content)
  1. 二进制内容响应
import requests   #导入 Requests 模块
r = requests.get('https://XXX')   #像目标url地址发送get请求,返回一个response对象
r.content   #非文本请求,获取响应内容,一般创建图片时获取图片使用

3. json内容响应

import requests    #导入 Requests 模块
r = requests.get('https://XXX')
r.json()

如果 JSON 解码失败,r.json就会抛出一个异常。例如,相应内容是 401 (Unauthorized),尝试访问 r.json将会抛出 ValueError: No JSON object could be decoded异常。

  1. 原始内容响应

在罕见的情况下,你可能想获取来自服务器的原始套接字响应,那么你可以访问 r.raw。 如果你确实想这么干,那请你确保在初始请求中设置了 stream=True。具体你可以这么做:

import requests
r = requests.get('https://XXX', stream=True)
r.raw   #<requests.packages.urllib3.response.HTTPResponse object at 0x101194810>
r.raw.read(10)  #'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'

三:BeautifulSoup介绍

1:BeautifulSoup介绍

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

BeautifulSoup文档地址:Beautiful Soup 4.4.0 文档    Beautiful Soup 4.12.0 文档

2:BeautifulSoup安装

pip install beautifulsoup4

我们还可以安装lxml,这是一个解析器,BeautifulSoup可以使用它来解析HTML,然后提取内容,如果不安装lxml,则BeautifulSoup会使用Python内置的解析器对文档进行解析。之所以使用lxml,是因为它速度快

pip install lxml

3:BeautifulSoup使用

(1):Tag介绍

标签; 访问方式:soup.tag;属性:tag.name(标签名),tag.attrs(标签属性)

例:

from bs4 import BeautifulSoup
soup = BeautifulSoup('<p class="test">this is test</p>','lxml')
tag = soup.p
print(tag) # <p class="test">this is test</p>
print(tag.name) # p
print(tag.attrs) # {'class': ['test']}
print(tag['class']) # ['test']

(2):NavigableString介绍

NavigableString就是标签中的文本内容(不包含标签),可遍历字符串; 访问方式:soup.tag.string

例:

from bs4 import BeautifulSoup
soup = BeautifulSoup('<p class="test">this is test</p>','lxml')

tag = soup.p
print(tag.string) #this is test

(3):BeautifulSoup介绍

BeautifulSoup 对象表示的是一个文档的全部内容.大部分时候,可以把它当作 Tag 对象,它支持 遍历文档树 和 搜索文档树 中描述的大部分的方法; 属性:soup.name(标签名),soup.attrs(标签属性)

(4):Comment介绍

标签内字符串的注释; 访问方式:soup.tag.string
例:

from bs4 import BeautifulSoup

soup = BeautifulSoup('<p><!--hello word--></p>','lxml')
tag = soup.p
print(tag.string) #hello word

(5):搜索文档树

在BeautifulSoup中最常用的是find()和find_all(),当然还有其他的。比如find_parent() 和 find_parents()、 find_next_sibling() 和 find_next_siblings() 、find_all_next() 和 find_next()、find_all_previous() 和 find_previous() 等等。这里只介绍find()和find_all()用法,其他的可以自行参考官网文档

  1. find_all()

搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件。返回值类型是bs4.element.ResultSet

语法

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

参数说明

  • name 参数:可以查找所有名字为 name 的tag。
  • attr 参数:就是tag里的属性。
  • string 参数:搜索文档中字符串的内容。
  • recursive 参数: 调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点。如果只想搜索tag的直接子节点,可以使用参数 recursive=False 。

简单实例:

from bs4 import BeautifulSoup
import re

soup = BeautifulSoup('<p class="test">this is test</p><a class="click" id="btn" href="http://www.baidu.com">点击跳转</a>','lxml')

print(soup.find_all("p")) #[<p class="test">this is test</p>]


print(soup.find_all("p", "test")) #[<p class="test">this is test</p>]

# 
print(soup.find_all("a")) #[<a class="click" href="http://www.baidu.com">点击跳转</a>]


print(soup.find_all(id="btn")) #[<a class="click" href="http://www.baidu.com" id="btn">点击跳转</a>]

print(soup.find_all(string=re.compile("test"))) #['this is test']
  1. find()

与find_all()类似,只不过只返回找到的第一个值。返回值类型是bs4.element.Tag。

语法

find( name , attrs , recursive , string , **kwargs )

参数说明

  • name 参数:可以查找所有名字为 name 的tag。
  • attr 参数:就是tag里的属性。
  • string 参数:搜索文档中字符串的内容。
  • recursive 参数: 调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点。如果只想搜索tag的直接子节点,可以使用参数 recursive=False 。

简单实例:

from bs4 import BeautifulSoup
import re

soup = BeautifulSoup('<p class="test">this is test</p><a class="click" id="btn" href="http://www.baidu.com">点击跳转</a>','lxml')

print(soup.find("p")) #<p class="test">this is test</p>


print(soup.find("p", "test")) #<p class="test">this is test</p>

# 
print(soup.find("a")) #<a class="click" href="http://www.baidu.com">点击跳转</a>


print(soup.find(id="btn")) #<a class="click" href="http://www.baidu.com">点击跳转</a>

print(soup.find(string=re.compile("test"))) #this is test

四:python实现数据爬虫

数据爬虫简单实例

import requests #导入requests 模块
from bs4 import BeautifulSoup  #导入BeautifulSoup 模块
import os  #导入os模块
class BeautifulPicture():
    def __init__(self):  #类的初始化操作
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1'}  #给请求指定一个请求头来模拟chrome浏览器
        self.web_url = 'http://XXX'  #要访问的网页地址
        self.folder_path = r'E:\pic'  #设置图片要存放的文件目录
    def get_pic(self):
        print('开始网页get请求')
        r = self.request(self.web_url)
        print('开始获取所有a标签')
        all_a = BeautifulSoup(r.text, 'lxml').find_all('img')  #获取网页中的class为cV68d的所有a标签
        print('开始创建文件夹')
        self.mkdir(self.folder_path)  #创建文件夹
        print('开始切换文件夹')
        os.chdir(self.folder_path)   #切换路径至上面创建的文件夹
        i = 0
        for a in all_a: #循环每个标签,获取标签中图片的url并且进行网络请求,最后保存图片
            img_str = a['src'] #a标签中完整的style字符串
            print('a标签的style内容是:', img_str)
            first_pos = img_str.find('"') + 1
            second_pos = img_str.find('"',first_pos)
            img_url = img_str[first_pos: second_pos] #使用Python的切片功能截取双引号之间的内容
            img_name = str(i)
            self.save_img(img_url, img_name) #调用save_img方法来保存图片
            i = int(i)+1
    def save_img(self, url, name): ##保存图片
        print('开始请求图片地址,过程会有点长...')
        if url.find('https') != -1:
            img = self.request(url)
            file_name = name + '.jpg'
            print('开始保存图片')
            f = open(file_name, 'ab')
            f.write(img.content)
            print(file_name, '图片保存成功!')
            f.close()
    def request(self, url):  #返回网页的response
        r = requests.get(url, headers=self.headers)  # 像目标url地址发送get请求,返回一个response对象。有没有headers参数都可以。
        return r
    def mkdir(self, path):  ##这个函数创建文件夹
        path = path.strip()
        isExists = os.path.exists(path)
        if not isExists:
            print('创建名字叫做', path, '的文件夹')
            os.makedirs(path)
            print('创建成功!')
        else:
            print(path, '文件夹已经存在了,不再创建')
beauty = BeautifulPicture()  #创建类的实例
beauty.get_pic()  #执行类中的方法

huaweichenai
635 声望114 粉丝