python爬虫_第三课_聚焦爬虫

Posted 一只特立独行的猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python爬虫_第三课_聚焦爬虫相关的知识,希望对你有一定的参考价值。

导言

聚焦爬虫:爬取页面中指定的页面内容。

编码流程:

1.指定url
2.发起请求
3.获取响应数据
4.数据解析
5.持久化存储

数据解析分类:

1.正则
2. bs4
3.xpath(***)

数据解析原理概述:

解析的局部的文本内容都会在标签之间或者标签对应的属性中进行存储
- 1.进行指定标签的定位
- 2.标签或者标签对应的属性中存储的数据值进行提取(解析)

正则表达式进行数据解析

爬取图片分析:

在网页中对图片右键另存为,可以得到该图片的URL地址,然后将图片以二进制的形式存储,就可以得到该图片。

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import requests
if __name__ == "__main__":
    #如何爬取图片数据
    url = 'https://pic.qiushibaike.com/system/pictures/12172/121721055/medium/9OSVY4ZSU4NN6T7V.jpg'
    #content返回的是二进制形式的图片数据
    # text(字符串) content(二进制)json() (对象)
    img_data = requests.get(url=url).content

    with open('./qiutu.jpg','wb') as fp:
        fp.write(img_data)

爬取整张网页的图片

1.根据requests得到html文件。
2.根据正则表达式匹配得到网页中所有目标图片的url。
3.多次发送get请求,得到所有图片。

代码

# -*- coding:utf-8 -*-
import requests
import re
import os
#需求:爬取糗事百科中糗图板块下所有的糗图图片
if __name__ == "__main__":
    #创建一个文件夹,保存所有的图片
    if not os.path.exists('./qiutuLibs'):
        os.mkdir('./qiutuLibs')

    url = 'https://www.qiushibaike.com/pic/'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'

    }
    #使用通用爬虫对url对应的一整张页面进行爬取
    page_text = requests.get(url=url,headers=headers).text

    #使用聚焦爬虫将页面中所有的糗图进行解析/提取
    ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
    img_src_list = re.findall(ex,page_text,re.S)
    # print(img_src_list)
    for src in img_src_list:
        #拼接出一个完整的图片url
        src = 'https:'+src
        #请求到了图片的二进制数据
        img_data = requests.get(url=src,headers=headers).content
        #生成图片名称
        img_name = src.split('/')[-1]
        #图片存储的路径
        imgPath = './qiutuLibs/'+img_name
        with open(imgPath,'wb') as fp:
            fp.write(img_data)
            print(img_name,'下载成功!!!')



爬取分页的图片

观察网页的每一页页面的url后发现,
第一页的url为:https://www.qiushibaike.com/pic/page/1/?s=5184961
第二页的url为:https://www.qiushibaike.com/pic/page/2/?s=5184961
推测1和2表示的是页数,通过
url = 'https://www.qiushibaike.com/pic/page/%d/?s=5184961’进行生成每一页,然后通过对每一页进行图片正则匹配和爬取,实现图片的爬取,将爬取后的图片放到一个文件夹里面。

# -*- coding:utf-8 -*-
import requests
import re
import os
#需求:爬取糗事百科中糗图板块下所有的糗图图片
if __name__ == "__main__":
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'

    }
    #创建一个文件夹,保存所有的图片
    if not os.path.exists('./qiutuLibs'):
        os.mkdir('./qiutuLibs')
    #设置一个通用的url模板
    url = 'https://www.qiushibaike.com/pic/page/%d/?s=5184961'
    # pageNum = 2

    for pageNum in range(1,3):
        #对应页码的url
        new_url = format(url%pageNum)


        #使用通用爬虫对url对应的一整张页面进行爬取
        page_text = requests.get(url=new_url,headers=headers).text

        #使用聚焦爬虫将页面中所有的糗图进行解析/提取
        ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
        img_src_list = re.findall(ex,page_text,re.S)
        # print(img_src_list)
        for src in img_src_list:
            #拼接出一个完整的图片url
            src = 'https:'+src
            #请求到了图片的二进制数据
            img_data = requests.get(url=src,headers=headers).content
            #生成图片名称
            img_name = src.split('/')[-1]
            #图片存储的路径
            imgPath = './qiutuLibs/'+img_name
            with open(imgPath,'wb') as fp:
                fp.write(img_data)
                print(img_name,'下载成功!!!')

bs4进行数据解析

原理介绍:

bs4进行数据解析
- 1.标签定位
- 2.提取标签、标签属性中存储的数据值
- bs4数据解析的原理:
- 1.实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
- 2.通过调用BeautifulSoup对象中相关的属性或者方法进行标签定位和数据提取

环境安装:

pip install bs4
pip install lxml

如何实例化BeautifulSoup对象:

from bs4 import BeautifulSoup
- 对象的实例化:
- 1.将本地的html文档中的数据加载到该对象中
fp = open(’./test.html’,‘r’,encoding=‘utf-8’)
soup = BeautifulSoup(fp,‘lxml’)
-
- 2.将互联网上获取的页面源码加载到该对象中
page_text = response.text
soup = BeatifulSoup(page_text,‘lxml’)
-
提供的用于数据解析的方法和属性:
- soup.tagName:返回的是文档中第一次出现的tagName对应的标签
- soup.find():
- find(‘tagName’):等同于soup.div
-
- 属性定位:
-soup.find(‘div’,class_/id/attr=‘song’)
- soup.find_all(‘tagName’):返回符合要求的所有标签(列表)
- select:
- select(‘某种选择器(id,class,标签…选择器)’),返回的是一个列表。
-
- 层级选择器:
- soup.select(’.tang > ul > li > a’):>表示的是一个层级
- oup.select(’.tang > ul a’):空格表示的多个层级
-
- 获取标签之间的文本数据:
- soup.a.text/string/get_text()
- text/get_text():可以获取某一个标签中所有的文本内容
- string:只可以获取该标签下面直系的文本内容
-
- 获取标签中属性值:
- soup.a[‘href’]

http://www.shicimingju.com/book/sanguoyanyi.html .网站中,想把所有的文本提取到一个txt文档里面。通过bs4定位到book-mulu类的a标签的href属性,然后对每个属性进行爬取。然后放入文件,就实现了文本的爬取。

代码:

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup
#需求:爬取三国演义小说所有的章节标题和章节内容http://www.shicimingju.com/book/sanguoyanyi.html
if __name__ == "__main__":
    #对首页的页面数据进行爬取
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'
    }
    url = 'http://www.shicimingju.com/book/sanguoyanyi.html'
    page_text = requests.get(url=url,headers=headers).text

    #在首页中解析出章节的标题和详情页的url
    #1.实例化BeautifulSoup对象,需要将页面源码数据加载到该对象中
    soup = BeautifulSoup(page_text,'lxml')
    #解析章节标题和详情页的url
    li_list = soup.select('.book-mulu > ul > li')
    fp = open('./sanguo.txt','w',encoding='utf-8')
    for li in li_list:
        title = li.a.string
        detail_url = 'http://www.shicimingju.com'+li.a['href']
        #对详情页发起请求,解析出章节内容
        detail_page_text = requests.get(url=detail_url,headers=headers).text
        #解析出详情页中相关的章节内容
        detail_soup = BeautifulSoup(detail_page_text,'lxml')
        div_tag = detail_soup.find('div',class_='chapter_content')
        #解析到了章节的内容
        content = div_tag.text
        fp.write(title+':'+content+'\\n')
        print(title,'爬取成功!!!')

结果展示:

结果出现了乱码,还在解决。

xpath进行解析

xpath解析:最常用且最便捷高效的一种解析方式。通用性。

xpath解析原理:

1.实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中。
- 2.调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获。

环境的安装:

pip install lxml

如何实例化一个etree对象:

from lxml import etree
1.将本地的html文档中的源码数据加载到etree对象中:
etree.parse(filePath)
- 2.可以将从互联网上获取的源码数据加载到该对象中
etree.HTML(‘page_text’)
- xpath(‘xpath表达式’)

xpath表达式:

- /:表示的是从根节点开始定位。表示的是一个层级。
- //:表示的是多个层级。可以表示从任意位置开始定位。
- 属性定位://div[@class=‘song’] tag[@attrName=“attrValue”]
- 索引定位://div[@class=“song”]/p[3] 索引是从1开始的。
- 取文本:
- /text() 获取的是标签中直系的文本内容
- //text() 标签中非直系的文本内容(所有的文本内容)
- 取属性:
/@attrName ==>img/src

爬取58二手房中的房源信息

代码:

通过epath对网页资源进行定位,然后匹配并存储。

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import requests
from lxml import etree
#需求:爬取58二手房中的房源信息
if __name__ == "__main__":
    headers = {
        'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
    }
    #爬取到页面源码数据
    url = 'https://bj.58.com/ershoufang/'
    page_text = requests.get(url=url,headers=headers).text

    #数据解析
    tree = etree.HTML(page_text)
    #存储的就是li标签对象
    li_list = tree.xpath('//ul[@class="house-list-wrap"]/li')
    fp = open('58.txt','w',encoding='utf-8')
    for li in li_list:
        #局部解析
        title = li.xpath('./div[2]/h2/a/text()')[0]
        print(title)
        fp.write(title+'\\n')

全国城市名称爬取

网页分析

f12检查网页源代码后,发现所有城市信息都在li标签中,所以只需要统计li标签的text值就可以实现城市名称的爬取。

代码

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import requests
from lxml import etree
#项目需求:解析出所有城市名称https://www.aqistudy.cn/historydata/
if __name__ == "__main__":
    # headers = {
    #     'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
    # }
    # url = 'https://www.aqistudy.cn/historydata/'
    # page_text = requests.get(url=url,headers=headers).text
    #
    # tree = etree.HTML(page_text)
    # host_li_list = tree.xpath('//div[@class="bottom"]/ul/li')
    # all_city_names = []
    # #解析到了热门城市的城市名称
    # for li in host_li_list:
    #     hot_city_name = li.xpath('./a/text()')[0]
    #     all_city_names.append(hot_city_name)
    #
    # #解析的是全部城市的名称
    # city_names_list = tree.xpath('//div[@class="bottom"]/ul/div[2]/li')
    # for li in city_names_list:
    #     city_name = li.xpath('./a/text()')[0]
    #     all_city_names.append(city_name)
    #
    # print(all_city_names,len(all_city_names))

    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
    }
    url = 'https://www.aqistudy.cn/historydata/'
    page_text = requests.get(url=url, headers=headers).text

    tree = etree.HTML(page_text)
    #解析到热门城市和所有城市对应的a标签
    # //div[@class="bottom"]/ul/li/          热门城市a标签的层级关系
    # //div[@class="bottom"]/ul/div[2]/li/a  全部城市a标签的层级关系
    a_list = tree.xpath('//div[@class="bottom"]/ul/li/a | //div[@class="bottom"]/ul/div[2]/li/a')
    all_city_names = []
    for a in a_list:
        city_name = a.xpath('./text()')[0]
        all_city_names.append(city_name)
    print(all_city_names,len(all_city_names))

以上是关于python爬虫_第三课_聚焦爬虫的主要内容,如果未能解决你的问题,请参考以下文章

Python爬虫第三课(提取数据)

Python爬虫第三课 网页爬取

Scrapy学习第三课

手把手教你写电商爬虫-第三课 实战尚妆网AJAX请求处理和内容提取

手把手教你写电商爬虫-第三课 实战尚妆网AJAX请求处理和内容提取

爬虫第三课:互联网中网页的解析