Python爬虫基础整理

一.爬虫分类

根据使用场景,网络爬虫可以分为通用爬虫和聚焦爬虫。

1.通用爬虫

通用爬虫是 捜索引擎抓取系统(Baidu、Google、Yahoo等)的重要组成部分。主要目的是将互联网上的网 页下载到本地,形成一个互联网内容的镜像备份。
通用网络爬虫 从互联网中搜集网页,采集信息,这些网页信息用于为搜索引擎建立索引从而提供支持,它决定着 整个引擎系统的内容是否丰富,信息是否即时,因此其性能的优劣直接影响着搜索引擎的效果。
Python爬虫基础整理_第1张图片

搜索引擎如何获取一个新网站的URL:

  1. 新网站向搜索引擎主动提交网址:
  2. 在其他网站上设置新网站外链
  3. 和DNS解析服务商(如DNSPod等)合作,新网站域名将被迅速抓取。

爬虫限制:
搜索引擎爬虫是被输入了一定的规则的,它需要遵从一些命令或文件的内容。

  1. rel=“nofollow”,,告诉搜索引擎爬虫无需抓取目标页,同时告诉搜索引擎无需将的当前页的Pagerank传递到目标页.
  2. Robots协议(也叫爬虫协议、机器人协议等),全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。

通用爬虫的局限性:
1.大多情况下,网页里90%的内容对用户来说都是无用的。
2. 搜索引擎无法提供针对具体某个用户的搜索结果。
3. 图片、数据库、音频、视频多媒体等不能很好地发现和获取。
4. 基于关键字的检索,难以支持根据语义信息提出的查询,无法准确理解用户的具体需求。

2.聚焦爬虫(需要学习的内容)

聚焦爬虫,是"面向特定主题需求"的一种网络爬虫程序,它与通用搜索引擎爬虫的区别在于:聚焦爬虫在实施网页 抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息。

二.HTTP和HTTPS

HTTP协议-80端口

HyperTextTransferProtocol, 超文本传输协议是一种发布和接收HTML页面的方法。

HTTPS-443端口

HypertextTransferProtocoloverSecureSocketLayer,
简单讲是HTTP的安全版,在HTTP下加入SSL 层。

网络爬虫抓取过程可以理解为模拟浏览器操作的过程。
浏览器发送HTTP请求的过程
1.当用户再浏览器的地址输入一个URL并按回车之后,浏览器会向HTTP服务器发送HTTP请求,HTTP请求分为GET和POST两种方法。
2.当我们再浏览器输入URL时,浏览器发送一个Request请求去获取目标网址的html文件,服务器把Response文件对象发送返回给浏览器。
3.浏览器分析Response中的HTML,发现其中引用了很多其他文件,比如Images文件,CSS文件,JS文件。浏览器会自动再次发送Request去获取图片,CSS文件,或者JS文件。
4. 当所有的文件都下载成功后,网页会根据HTML语法结构,完整的显示出来了。

三.客户端HTTP请求

1.请求方法
根据HTTP标准,HTTP请求可以使用多种请求方法.
HTTP0.9:只有基本的文本GET功能。
HTTP1.0:完善的请求/响应模型,并将协议补充完整,定义了三种请求方法:GET,POST和HEAD方法。
HTTP1.1:在1.0基础上进行更新,新增了五种请求方法 OPTIONS,PUT,DELETE,TRACE和CONNECT方法。

Python爬虫基础整理_第2张图片
Get 和 Post 详解

  1. GET是从服务器上获取数据,POST是向服务器传送数据
  2. GET请求参数显示,都显示在浏览器网址上,即“Get”请求的参数是URL的一部分。
  3. POST请求参数在请求体当中,消息长度没有限制而且以隐式的方式进行发送,通常用来向HTTP服务器提交量比较大的数据(比如请求中包含许多参数或者文件上传操作等),请求的参数包含在“Content-Type”消息头里,指明该消息体的媒体类型和编码,

四.HTTP响应

HTTP响应由四个部分组成,分别是: 状态行 、 消息报头 、 空行 、 响应正文
Python爬虫基础整理_第3张图片
响应状态码
Python爬虫基础整理_第4张图片常用的状态响应码
200: 请求成功
302: 请求页面临时转移至新url
307和304: 使用缓存资源
404: 服务器无法找到请求页面
403: 服务器拒绝访问,权限不够
500: 服务器遇到不可预知的情况

Cookie和Session
服务器和客户端的交互仅限于请求/响应过程,结束之后便断开,在下一次请求时,服务器会认为新的客户端。为了维护他们之间的链接,让服务器知道这是前一个用户发送的请求,必须在一个地方保存客户端的信息。
Cookie:通过在客户端记录的信息确定用户的身份。
Session:通过在服务器端记录的信息确定用户的身份。

五.爬虫实现百度图片下载器

#coding:utf-8
#date:2020/4/89:25
#author:CQ_Liu

import os
import re

import requests
from colorama import Fore


def download_image(url, keyword):
    """
    下载图片
    :param url: 百度图片的网址
    :return: Bool
    """
    #  1. 向服务器发起HTTP请求
    response = requests.get(url)
    #  2. 获取服务器端的响应信息
    #  响应信息: status_code, text, url
    data = response.text
    #  3. 编写正则表达式,获取图片的网址
    # "ObjURL":"http:\/\/img2.imgtn.bdimg.com\/it\/u=3459137507,1368309920&fm=214&gp=0.jpg"
    # 获取到的: http:\/\/img2.imgtn.bdimg.com\/it\/u=3459137507,1368309920&fm=214&gp=0.jpg
    # 正则的语法: .代表除了\n之外的任意字符, *代表前一个字符出现0次或者无数次. ?非贪婪模式
    pattern = r'"ObjURL":"(.*?)"'
    # 4. 根据正则表达式寻找符合条件的图片网址.
    image_urls = re.findall(pattern, data)
    # 5. 下载猫的图片到本地
    index = 1
    for image_url in image_urls:
        # 转义字符: \n, \t, \ , \\,
        image_url = image_url.replace('\\', '')
        print(image_url)  # 'xxxx.jpg   xxxx.png'
        # response.text返回unicode的文本信息, response.content返回bytes类型的信息
        try:
            response = requests.get(image_url)
        except Exception as e:
            print(Fore.RED + "[-]下载失败: %s" % (image_url))
        else:
            old_image_filename = image_url.split('/')[-1]
            if old_image_filename:
                image_format = old_image_filename.split('.')[-1]
                # jpeg?imageview&thumbnail=550x0
                if '?' in image_format:
                    image_format = image_format.split('?')[0]
            else:
                image_format = 'jpg'

            # 生成图片的存储目录, keyword='cat', 'dog', 'python django'
            keyword = keyword.replace(' ', '_')
            print(keyword)
            if not os.path.exists(keyword):
                os.mkdir(keyword)
            image_filename = os.path.join(keyword, str(index) + '.' + image_format)

            with open(image_filename, 'wb') as f:
                f.write(response.content)
                print(Fore.BLUE + "[+] 保存图片%s.jpg成功" % (index))
                index += 1

if __name__ == '__main__':
    keyword = input("请输入批量下载图片的关键字: ")
    # url地址里面参数信息可以长可以短, 有的参数可以省略的。
    url = 'http://image.baidu.com/search/index?tn=baiduimage&word=' + keyword
    print(Fore.BLUE + '[+] 正在请求网址: %s' % (url))
    download_image(url, keyword)

六.网络数据采集requests库

requests官方网址
requests方法汇总
Python爬虫基础整理_第5张图片response对象汇总

Response对象包含服务器返回的所有信息,也包含请求的Request信息。

Python爬虫基础整理_第6张图片
高级应用一: 添加 headers
UserAgent是识别浏览器的一串字符串,相当于浏览器的身份证,在利用爬虫爬取网站数据时,频繁更换UserAgent可以避免触发相应的反爬机制。fake-useragent对频繁更换UserAgent提供了很好的支持,可谓防反扒利器。

#coding:utf-8
#date:2020/4/108:58
#author:CQ_Liu
import requests
from fake_useragent import  UserAgent

def add_headers():
    # headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'}
    # UserAgent实质上是从网络获取所有的用户代理, 再通过random随机选取一个用户代理。
    # https://fake-useragent.herokuapp.com/browsers/0.1.11
    ua = UserAgent()
    # 默认情况下, python爬虫的用户代理是python-requests/2.22.0。
    response = requests.get('http://127.0.0.1:5000', headers={'User-Agent': ua.random})
    print(response)


if __name__ == '__main__':
    add_headers()

高级应用二: IP代理设置
在进行爬虫爬取时,有时候爬虫会被服务器给屏蔽掉,这时采用的方法主要有降低访问时间,通过代理IP访问。ip可以从网上抓取**(西刺代理)**,或者某宝购买。

#coding:utf-8
#date:2020/4/109:15
#author:CQ_Liu
import requests
from fake_useragent import UserAgent

ua = UserAgent()
proxies = {
    'http': 'http://222.95.144.65:3000',
    'https': 'https://182.92.220.212:8080'
}
response = requests.get('http://47.92.255.98:8000',
                        headers={'User-Agent': ua.random},
                        proxies=proxies
                        )

print(response)
# 这是因为服务器端会返回数据: get提交的数据和请求的客户端IP
# 如何判断是否成功? 返回的客户端IP刚好是代理IP, 代表成功。
print(response.text)

七.京东商品定向爬取

#coding:utf-8
#date:2020/4/109:34
#author:CQ_Liu
from urllib.error import HTTPError

import requests
from colorama import Fore
from fake_useragent import UserAgent


def download_page(url, parmas=None):
    try:
        ua = UserAgent()
        headers = {'User-Agent': ua.random}
        response = requests.get(url, params=parmas, headers=headers)
    except  HTTPError as e:
        print(Fore.RED + '[-] 爬取网站%s失败: %s' % (url, e.reason))
        return None
    else:
        # content返回的是bytes类型
        return response.content


def download_file(content=b'', filename='hello.html'):
    """
    :param content: 要写入本地的html字符bytes类型
    :param filename: 写入本地的文件名
    :return:
    """
    with open(filename, 'wb') as f:
        f.write(content)
        print(Fore.GREEN + '[+]写入文件%s成功' % (filename))


if __name__ == '__main__':
    # url = 'https://item.jd.com/100012015170.html'
    # html = download_page(url)
    # download_file(content=html)
    url = 'https://www.so.com/s'
    params = {
        'q': 'python'
    }
    content = download_page(url, params)
    download_file(content)

八.有道词典的爬虫(post提交)

需求: 输入英文单词, 返回中文的解释

你可能感兴趣的:(python)