python爬虫:聚焦爬虫,爬取指定页面的内容(连续爬取多个页面)--图片 评论爬虫 全国热门城市爬取

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

    ---编码流程:指定Url;发起请求;获取响应数据;数据解析;持久化存储;

数据解析分类:正则;bs4;xpath;

数据解析原理概述:

解析的局部文本内容都会在标签之间或者标签对应属性中进行存储

  1. 进行指定标签的定位

  2. 标签或者标签对应的属性中存储的数据值进行提取(解析)

1.1正则解析 

#需求:爬取图片
import requests
if __name__ == '__main__':
    #如何爬取图片数据
    url='你想要爬取网页的url'
    #content返回的是二进制形式的图片数据
    #text(字符串) content(二进制) json() (对象)
    img_data=requests.get(url=url).content
    with open('./xx.jpg','wb') as fp:
        fp.write(img_data)

#需求:糗事百科爬取某个板块下所有的图片
import requests
import re
import os
if __name__ == '__main__':
    #创建一个文件夹,保存所有图片
    if not os.path.exists('./xxx')
        os.mkdir('./xxx')
    url='xxxx'
    headers={
        'User-Agent':xxx
    }
    #使用通用爬虫对url对应的一整张页面进行爬取
    page_text=requests.get(url=url,headers=headers).text
    #使用聚焦爬虫将页面中所有糗事图片进行解析/提取
    ex='
.*?' img_src_list=re.findall(ex,page_text,re.S) for src in img_src_list: #拼接出完整的图片url src ='https:'+src #请求到了图片的二进制数据 img_data=requests.get(url=src,headers=headers).content #生成图片名称 img_name=src.split('/')[-1] #图片存储的路径 img_Path='./xxx/'+img_name with open(img_Path,'wb') as fp: fp.write(img_data) print(img_name,'下载成功!!!')
#可以直接爬取下一页的内容
import requests
import re
import os
if __name__ == '__main__':
    headers={
        'User-Agent':xxx
    }
    #创建一个文件夹,保存所有图片
    if not os.path.exists('./xxx')
        os.mkdir('./xxx')
    #设置一个通用url模板
    url='https://www.qiushibaike.com/pic/page/%d/?s=5184961'
    # pageNum=2
    for pageNum in range(1,36):
        new_url=format(url%pageNum)
        #使用通用爬虫对url对应的一整张页面进行爬取
        page_text=requests.get(url=new_url,headers=headers).text
        #使用聚焦爬虫将页面中所有糗事图片进行解析/提取
        ex='
.*?' img_src_list=re.findall(ex,page_text,re.S) for src in img_src_list: #拼接出完整的图片url src ='https:'+src #请求到了图片的二进制数据 img_data=requests.get(url=src,headers=headers).content #生成图片名称 img_name=src.split('/')[-1] #图片存储的路径 img_Path='./xxx/'+img_name with open(img_Path,'wb') as fp: fp.write(img_data) print(img_name,'下载成功!!!')

1.2 bs4解析

解析原理:

  1. 标签定位

  2. 提取标签、标签属性中存储的数据值 

  • 实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
  • 通过调用BeautifulSoup对象中相关的属性或者方法进行标签定位和数据提取
#环境安装
pip install bs4
pip install lxml

 对象实例化

# 第一种方法:将本地的html文档中的数据加载到该对象中
fp=open('./test.html','r',encoding='utf-8')
soup=BeautifulSoup(fp,'lxml')
#第二种方法:将互联网获取的页面源码加载到该对象中
page_text=response.text

数据解析的方法和属性

  • soup.tagName:返回的是文档中第一次出现的tagName对应的标签
  • soup.find():
    • find('tagName'):等同于soup.div
    • 属性定位:
      • soup.find('div',class_/id/attr='song')
  • soup.find_all('tagName'):返回符合要求的所有标签(列表) 

2.select

        select('某种选择器(id,class,标签…选择器)'),返回的是一个列表

        soup.select('.tang>ul>li>a'):>表示一个层级

        soup.select('.tang>ul a'):空格表示多个层级

获取标签之间的文本数据

        soup.a.text/string/get_text()

        text/get_text():可以获取某一个标签中所有的文本内容

        string:只可以获取该标签下的直系文本内容

获取标签中属性值

        soup.a['href']

#需求:爬取三国演义小说的所有章节标题和章节内容
#url:www.shicimingju.com/book/sanguoyanyi.html
import requests
from bs4 import BeautifulSoup
if __name__ == '__main__':
    headers={
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'
    }
    url='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.csv','w',encoding='utf-8')
    for li in li_list:
        title=li.a.string
        detail_url='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_context')
        #解析到章节的内容
        content=div_tag.text
        fp.write(title':'+content+'\n')
        print(title)

1.3xpath

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

解析原理:

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

 环境安装:

pip install lxml

如何实例化:

  1. 将本地html文档中的源码数据加载到etree对象中:etree.parse(filePath)
  2. 可以将从互联网上获取的源码数据加载到该对象中:etree.HTML('page_text')

 xpath(‘xpath表达式’)

#本地化
from lxml import etree
if __name__ == '__main__':
    #实例化好了一个etree对象,且将被解析
    tree=etree.parse('test.html')
    r=tree.xpath('/html/head/title')
    print(r)

xpath表达式:

  1. /:表示 的是从根节点开始定位,表示一个层级。
  2. //:表示多个层级,可以表示从任意位置开始定位。
  3. 属性定位://div[@class='song'] tag[@attrName="attrValue"]
  4. 索引定位://div[@class="song"]/p[3] 索引是从1开始的。

 取文本:

  • /text():获取的是标签中直系的文本内容
  • //text():标签中非直系的文本内容(所有的文本内容)

 取属性:

  • /@attrName   ==>img/src

案例 

#需求:爬取58二手房的信息
import requests
from lxml import etree
if __name__ == '__main__':
    headers={
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'
    }
    #爬取到页面源码数据
    url='https://bj.58.com/ershoufang/'
    page_text=requests.get(url=url,headers=headers).text
    #数据解析
    tree=etree.HTML(page_text)
    li_list=tree.xpath('//ul[@class="houser-list-wrap"]/li')
    fp=open('58.csv','w',encoding='utf-8')
    for li in li_list:
        #局部解析
        title=li.xpath('./div[2]/h2/a/text()')[0]
        print(title)
        fp.write(title+'\n')

#需求:解析下载图片数据
import requests
from lxml import etree
import os
if __name__ == '__main__':
    headers={
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'
    }
    #爬取到页面源码数据
    url='https://pic.netbian.com/4kmeinv/'
    response=requests.get(url=url,headers=headers)
    response.encoding='utf-8'

    page_text=response.text
    #数据解析
    tree=etree.HTML(page_text)
    li_list=tree.xpath('//div[@class="slist"]/ul/li]')
    #创建一个文件夹
    if not os.path.exists('./picLibs'):
        os.mkdir('./picLibs')
    for li in li_list:
        img_src='https://pic.netbian.com'+li.xpath('./a/img/@src')[0]
        img_name=li.xpath('./a/img/@alt')[0]+'.jpg'
        #通用处理中文乱码的解决方案
        img_name=img_name.encode('iso-8859-1').decode('gbk')
        print(img_name,img_src)
        #请求图片进行持久化存储
        img_data=requests.get(url=img_src,headers=headers).content
        img_path='./picLibs/'+img_name
        with open(img_path,'wb') as fp:
            fp.write(img_data)
            print(img_name,'下载成功!!!')
#需求:爬取全国城市名称
import requests
from lxml import etree
import os
if __name__ == '__main__':
    headers={
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'
    }
    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_names=li.xpath('./a/text()')[0]
        all_city_names.append(city_names)

    print(all_city_names,len(all_city_names))



    #div[@class="bottom"]/ul/li/ 热门城市a标签的层级关系
    # div[@class="bottom"]/ul/div[2]/li/a 全部城市a标签的层级关系

课程资源来源于网络 ,文章均为原创,如转载请注明出处!!!

你可能感兴趣的:(python爬虫,python,爬虫,开发语言)