爬虫初接触


前言

本人刚开始学习爬虫,里面的代码大都是从老师给的ppt所截,如有问题请多多指正。代码都属基础代码,相对简单,适合纯入门…


一、爬虫是什么?

随着网络的迅速发展,万维网成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战,网络爬虫应运而生。 网络爬虫 (又被称为网页蜘蛛、网络机器人),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。下图展示一下网络爬虫在互联网中起到的作用:

pc
网络爬虫的基本工作流程:

  1. 首先选取一部分精心挑选的种子URL。
  2. 将这些URL放入待抓取URL队列。
  3. 从待抓取URL队列中读取待抓取队列的URL,解析DNS,并且得到主机的IP,并将URL对应的网页下载下来,存储进已下载网页库中。此外,将这些URL放进已抓取URL队列。
  4. 分析已抓取URL队列中的URL,从已下载的网页数据中分析出其他URL,并和已抓取的URL进行比较去重,最后将去重过的URL放入待抓取URL队列,从而进入下一个循环。

基本工作流程可参见下图:
pc

二、前期知识储备

学习者需要预先掌握Python的数字类型、字符串类型、循环、函数、列表类型、字典类型、文件和第三方库使用等概念和编程方法。
pc

1.发送请求

使用http库向目标站点发起请求,即发送一个request,request包含:请求头、请求体等。
requests模块缺陷: 不能执行JS 和CSS 代码。

2.获取响应内容

如果requests的内容存在于目标服务器上,那么服务器会返回请求内容。
Response包含: html、Json字符串、图片,视频等。

3.解析内容

对用户而言,就是寻找自己需要的信息。对于Python爬虫而言,就是利用正则表达式或者其他库提取目标信息。

解析html数据: 正则表达式(RE模块),第三方解析库如Beautifulsoup,xpath等
解析json数据: json模块
解析二进制数据: 以wb的方式写入文件

4.保存数据

解析得到的数据可以多种形式,如文本,音频,视频保存在本地。

数据库(MySQL,Mongdb、Redis)

文件

三、爬虫知识

1.requests库

requests是Python的一个http请求库。requests官方文档
Win平台:以“管理员身份运行cmd”,其他系统打开终端即可,执行
pip install requests
pc
测试:
pc

requests库的2个主要方法

方法说明
requests.get()获取HTML网页的主要方法,对应HTTP的GET
requests.post()向HTML网页提交POST请求的方法,对应HTTP的POST

requests.get(url,**kwargs) or requests.post(url,**kwargs)

url: 获取页面的url链接
**kwargs: 控制访问的参数,均为可选项,共以下13个
官方中文文档

pc

实例

有了 requests, 我们可以发送多个 method 的请求. 比如 get. 我们模拟一下百度的搜索:

首先我们需要观察一下百度搜索的规律. 在百度搜索框中写上“动物世界” 我们发现它弹出了一串很长的网址:
pc
但是仔细一看, 和 “动物世界” 有关的信息,只有前面一小段 (“s?wd=动物世界”),其他的对我们来说都是无用的信息。 所以我们尝试一下如果把后面的”无用”url 都去掉会怎样? ——我们还是能搜到 “动物世界”。
pc
所以 s?wd=动物世界 这就是我们搜索需要的关键信息。我们就能用get 来搭配一些自定义的搜索关键词来用 python 个性化搜索。 首先,我们固定不动的网址部分是 http://www.baidu.com/s? 后面的东西都是一些参数 (params), 所以我们将这些 params 用 python 的字典代替, 然后传入 requests.get() 功能。然后我们还能用 python (webbrowser模块) 打开一个你的默认浏览器, 观看你是否在百度的搜索页面.

import requests
import webbrowser
param = {"wd": "动物世界"}  # 搜索的信息
r = requests.get('http://www.baidu.com/s', params=param)
print(r.url)
webbrowser.open(r.url)

运行结果:(点开连接后依旧是“动物世界”连接
pc
pc

pc

import requests
def getHTMLText(url):
    try:
        r = requests.get(url,timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return "产生异常"
 
if __name__ == "__main__":
    url = "http://www.baidu.com"
    print(getHTMLText(url))

pc
注意: 网络连接有风险。异常处理很重要。raise_for_status()如果不等于200则产生异常requests.HTTPError。

2.网络爬虫的“盗亦有道”——Robots协议

Robots 是网站跟爬虫间的协议,robots.txt(统一小写)是一种存放于网站根目录下的ASCII编码的文本文件,它通常告诉网络搜索引擎的漫游器(又称网络蜘蛛),此网站中的哪些内容是不应被搜索引擎的漫游器获取的,哪些是可以被漫游器获取的。因为一些系统中的URL是大小写敏感的,所以robots.txt的文件名应统一为小写。robots.txt应放置于网站的根目录下。

典型就是现在国内搜索引擎百度、今日头条或者微信公众号等闭塞的消息渠道,是搜索不到的
pc

import requests
def getHTMLText(url: str):
    """
    获取京东商品页
    :param url: 京东商品页url
    :return: 
    """
    try:
        r = requests.get(url, headers={
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36'
        }, timeout=30)
        return r.text[:1000]
    except:
        return "产生异常"
if __name__ == "__main__":
    url = "https://item.jd.com/5089267.html"
    print(getHTMLText(url))

结果:
pc
网页:
pc

3.网页结构

pc

在 HTML 中, 基本上所有的实体内容, 都会有个 tag 来框住它。而这个被 tag 住的内容, 就可以被展示成不同的形式, 或有不同的功能。主体的 tag 分成两部分, headerbody

header 中, 存放这一些网页的网页的元信息, 比如说 title,这些信息是不会被显示到你看到的网页中的。这些信息大多数时候是给浏览器看, 或者是给搜索引擎的爬虫看。

HTML 的第二大块是 body, 这个部分才是你看到的网页信息. 网页中的 heading, 视频, 图片和文字等都存放在这里。这里的 <h1></h1> tag 就是主标题, 我们看到呈现出来的效果就是大一号的文字。<p></p> 里面的文字就是一个段落。<a></a>里面都是一些链接. 所以很多情况, 东西都是放在这些 tag 中的。爬虫想要做的就是根据这些 tag 来找到合适的信息。

我们了解了网页 (html) 的基本构架, 知道了爬网页就是在这个构架中找到需要的信息. 那么找到需要的信息时, BeautifulSoup,和xpath 就是一个找信息好帮手. 它能帮你又快有准地找到信息. 大大简化了使用难度。

4.etree解析网页

安装

pip install lxml

使用

  • 选着要爬的网址 (url)
  • 使用 python 登录上这个网址 (requests等)
  • 读取网页信息 (text出来)
  • 将读取的信息放入etree.HTML()

实例

Demo 获取京东商品属性
目标链接(京东Iphone8页面)

import requests
from lxml import etree
def get_jd_html(url: str):
    """
    获取京东商品属性
    :param url: 京东商品详情url
    :return: None
    """
    _response = requests.get(url, headers={
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36'
    })
    _html = etree.HTML(_response.text)
    a = _html.xpath('//*[@id="detail"]/div[2]/div[1]/div[1]/ul[3]/li/text()')
    print(a)
if __name__ == '__main__':
    goods_detail_url = 'https://item.jd.com/5089269.html'
    get_jd_html(url=goods_detail_url)

pc
结果:

['商品名称:AppleiPhone 8', '商品编号:5089269', '商品毛重:400.00g', '商品产地:中国大陆', 'CPU型号:其他', '运行内存:其他', '机身存储:64GB', '存储卡:不支持存储卡', '摄像头数量:后置单摄', '后摄主摄像素:1200万像素', '前摄主摄像素:其他', '主屏幕尺寸(英寸):4.7英寸', '分辨率:其它分辨率', '屏幕比例:其它屏幕比例', '屏幕前摄组合:其他', '充电器:其他', '热点:无线充电', '特殊功能:语音命令', '操作系统:iOS(Apple)']

5.处理json数据

json是JavaScript程序编写数据结构的原生方式,在Python中,字典的格式和json格式在显示上是一样的,但是字典是dict,而json是str。那么如何将一个字符串类型的dict或list转换成实实在在的dict和list呢,请往下看。

Python的json模块主要包含两大函数:
json.dumps 将python数据类型转化成json数据
json.loads 将json数据转化成python数据类型

举例: 取到一个网友评论某视频的json数据:
字典样式 '{"name":"gzj", "age":"23", "sex":"man"}'
列表样式 '["gzj", 23, "man"]'
字典和列表相互嵌套的样式 ["gzj", "{'age':'23'}
特别注意JSON字符串中的内容用双引号,而非单引号。若存在嵌套的情况,则最外层用' '中间的内容" "表示。
pc

6.Ajax请求

Ajax: 全称是异步的JavaScript和xml,不是一门专门的编程语言,而是利用JavaScript 在保证页面不被整体刷新的情况下与服务器交换数据并且更新部分网页显示的技术。例如在逛淘宝的时候,我们可以发现在网页下滑时可以看到最新的内容,这个加载的过程就是Ajax加载的过程。发送Ajax请求到网页更新的过程中,简单来说可以分为3步:发送请求,解析内容、渲染页面。

如何判断ajax请求,-------网站不刷新页面返回内容

都是处于XHR 标签下或者JS标签下

pc
我们发现这个是get请求
pc

实例

解析你喜欢b站的视频评论,并优雅的打印到控制面板

import requests
def get_bili_ajax(url: str):
    """
    获取bilibili 评论
    :param url: 评论url
    :return: None
    """
    _response = requests.get(url, headers={
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36'
    })
    bili_json = _response.json()
    for key, values in enumerate(bili_json['data']['replies']):
        message: str = values['content']['message']
        like_num: int = values['like']
        print(key, ' 楼评论: ', message, ' 赞同数量:', like_num)
if __name__ == '__main__':
    bili_url = 'https://api.bilibili.com/x/v2/reply?jsonp=jsonp&pn=2&type=1&oid=90748352&sort=2&_=1600263075329'
    get_bili_ajax(url=bili_url)

tips:
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中
pc


四、Scrapy

1.Scrapy介绍

Scrapy 是一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速、简单、可扩展的方式从网站中提取所需的数据。但目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。

所谓 框架 其实就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等)的具有很强通用性的项目模板。对于框架的学习,重点是要学习其框架的特性、各个功能的用法即可。

scrapy和requests、xpath的关系,可以做如下类比:
pc
Scrapy 是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架。因此Scrapy使用了一种非阻塞(又名异步)的代码来实现并发(基于Twisted实现单线程并发下载页面)。也具备解析下载内容功能、帮助实现“递归”、帮助完成数据持久化(数据写入硬盘或数据库)、还具备一些扩展性功能(自定义组件)。

2.Scrapy核心组件

pc

我们看到图里有这么几个东西,分别是:

  1. Spiders:爬虫,定义了爬取的逻辑和网页内容的解析规则,主要负责解析响应并生成结果和新的请求
  2. Engine:引擎,处理整个系统的数据流处理,出发事物,框架的核心。
  3. Scheduler:调度器,接受引擎发过来的请求,并将其加入队列中,在引擎再次请求时将请求提供给引擎
  4. Downloader:下载器,下载网页内容,并将下载内容返回给spider
  5. ItemPipeline:项目管道,负责处理spider从网页中抽取的数据,主要是负责清洗,验证和向数据库中存储数据
  6. Downloader Middlewares:下载中间件,是处于Scrapy的Request和Requesponse之间的处理模块
  7. Spider Middlewares:spider中间件,位于引擎和spider之间的框架,主要处理spider输入的响应和输出的结果及新的请求middlewares.py里实现

3.使用流程

1.创建一个工程

切换到项目目录后,执行创建项目的命令,爬虫项目即创建成功。

$ scrapy startproject bilibili(工程名称)

目录结构
用pycharm打开创建的工程,可以看到如下目录结构。
pc

2.创建爬虫应用程序

cd bilibili
scrapy genspider bili   https://www.bilibili.com 

执行成功后,就可以在项目的spiders目录下找到新生成的爬虫文件了。

创建爬虫程序语法

scrapy genspider 应用名称 爬取网页的起始url
# -*- coding: utf-8 -*-
import scrapy
class BiliSpider(scrapy.Spider):  # Spider是所有爬虫的父类
    name = 'bili'  # 爬虫文件的名称:通过爬虫文件的名称可以指定定位到某一个具体的爬虫文件
    allowed_domains = ['https://www.bilibili.com']  # 允许的域名:只爬取指定域名下的页面数据
    def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
            'http://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

def parse(self, response):
    filename = response.url.split("/")[-2] # 获取url,用”/”分段,获去倒数第二个字段
    with open(filename, 'a') as f:
        f.write(response.body) # 把访问的得到的网页源码写入文件
    yield {message: response.xpath('/html/head/title/text()').extract_first()}

在items.py文件中定义字段,这些字段用来保存数据,方便后续的操作。

# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html
import scrapy

class BilibiliItem(scrapy.Item):
    # define the fields for your item here like:
    message= scrapy.Field()
    pass

Scrapy基础使用

在pipelines.py中完成对数据进行持久化的操作。
利用Pipeline我们可以完成以下操作:

清理HTML数据,验证爬取的数据。
丢弃重复的不必要的内容。
将爬取的结果进行持久化操作。(存入数据库)

修改settings.py文件对项目进行配置。

ROBOTSTXT_OBEY = True
ITEM_PIPELINES = {
    'douban.pipelines.DoubanPipeline': 400,
}
DOWNLOADER_MIDDLEWARES = {
  'douban.middlewares.DoubanDownloaderMiddleware': 543,
}
scrapy crawl bili  #启动爬虫

总结

创建项目:scrapy startproject xxx
进入项目:cd xxx 进入某个文件夹下
创建爬虫:scrapy genspider xxx(爬虫名) xxx.com (爬取域)
生成文件:scrapy crawl xxx -o xxx.json (生成某种类型的文件)
运行爬虫:scrapy crawl XXX
列出所有爬虫:scrapy list
获得配置信息:scrapy settings [options]

总结

以上就是今天总结的爬虫内容,本文代码偏简单,作者也是爬虫小白,如有问题和错误请多多指教!!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值