Python爬虫(四)

Python爬虫(四)

一、案例:爬取站长素材图片

# 需求 下载前十页的图片
# 第一页:https://sc.chinaz.com/tupian/qinglvtupian.html
# 第二页:https://sc.chinaz.com/tupian/qinglvtupian_2.html
import urllib.request
from lxml import etree
def creat_request(page):
    if(page == 1):
        url = 'https://sc.chinaz.com/tupian/qinglvtupian.html'
    else:
        url = 'https://sc.chinaz.com/tupian/qinglvtupian_' + str(page) + '.html'
    headers = {
    
    
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44'
    }
    request = urllib.request.Request(url=url,headers=headers)
    return request

def get_content(request):
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    return content
def down_load(content):
    # 下载图片
    tree = etree.HTML(content)
    name_list = tree.xpath("//div[@id='container']//a/img/@alt")
    # 一般涉及图片的网站会有懒加载
    src_list = tree.xpath("//div[@id='container']//a/img/@src")
    # print(len(name_list),len(src_list))
    for i in range(len(name_list)):
        name = name_list[i]
        src = src_list[i]
        url = 'https:' + src
        url = url.replace('_s','')  # 将链接中的 _s 删除可以下载到高清图片
        urllib.request.urlretrieve(url = url,filename='./file/' + name + '.jpg')

if __name__ == '__main__':
    start_page = int(input('请输入起始页码'))
    end_page = int(input('请输入结束页码'))
    for page in range (start_page,end_page+1):
        # (1) 请求对象的定制
        request = creat_request(page)
        # (2) 获取网页源码
        content = get_content(request)
        # (3) 下载
        down_load(content)

在这里插入图片描述

二、JsonPath爬取json数据

1.安装JsonPath

pip install jsonpath -i https://pypi.douban.com/simple

2.解析json案例
json数据

{
    
    "store": {
    
    
    "book": [
      {
    
     "category": "修真",
        "author": "六道",
        "title": "坏蛋是怎样炼成的",
        "price": 8.95
      },
      {
    
     "category": "修真",
        "author": "我吃西红柿",
        "title": "吞噬星空",
        "price": 9.96
      },
      {
    
     "category": "修真",
        "author": "唐家三少",
        "title": "斗罗大陆",
        "price": 9.45
      },
      {
    
     "category": "修真",
        "author": "南派三叔",
        "title": "新城变",
        "price": 8.72
      }
    ],
    "bicycle": {
    
    
      "color": "黑色",
      "price": 19.95
    }
  }
}

(1)获取书店所有作者

import json
import jsonpath
obj = json.load(open('file/jsonpath.json','r',encoding='utf-8'))
# 书店所有作者  book[*]所有书   book[1]第一本书
author_list = jsonpath.jsonpath(obj,'$.store.book[*].author')
print(author_list)

(2)获取所有的作者

# 所有的作者
author_list = jsonpath.jsonpath(obj,'$..author')
print(author_list)

(3)store下面的所有元素

# store下面的所有元素
tag_list = jsonpath.jsonpath(obj,'$.store.*')
print(tag_list)

(4)store下面的所有钱

# store下面的所有钱
price_list = jsonpath.jsonpath(obj,'$.store..price')
print(price_list)

(5)第三本书

# 第三本书
book = jsonpath.jsonpath(obj,'$..book[2]')
print(book)

(6)最后一本书

# 最后一本书
book = jsonpath.jsonpath(obj,'$..book[(@.length - 1)]')
print(book)

(7)前两本书

# 前两本书
book_list = jsonpath.jsonpath(obj,'$..book[0,1]') #等价于下一种写法
book_list = jsonpath.jsonpath(obj,'$..book[:2]')
print(book_list)

(8)过滤出版本号 条件过滤需要在圆括号的前面添加问号

# 过滤出版本号  条件过滤需要在圆括号的前面添加问号
book_list = jsonpath.jsonpath(obj,'$..book[?(@.isbn)]')
print(book_list)

(9)那本书超过9元

# 那本书超过9元
book_list = jsonpath.jsonpath(obj,'$..book[?(@.price>9.8)]')
print(book_list)

三、JsonPath解析淘票票案例

import urllib.request

url = 'http://dianying.taobao.com/cityAction.json?activityId&_ksTS=1656042784573_63&jsoncallback=jsonp64&action=cityAction&n_s=new&event_submit_doGetAllRegion=true'
headers ={
    
    
    # ':authority': ' dianying.taobao.com',
    # ':method': ' GET',
    # ':path': ' /cityAction.json?activityId&_ksTS=1656042784573_63&jsoncallback=jsonp64&action=cityAction&n_s=new&event_submit_doGetAllRegion=true',
    # ':scheme': ' https',
    'accept':'*/*',
    # 'accept-encoding': ' gzip, deflate, br',
    'accept-language':'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
    'cookie':'cna=zIsvG8QofGgCAXAc0HQF5jMC;ariaDefaultTheme=undefined;xlly_s=1;t=9ac1f71719420207d1f87d27eb676a4c;cookie2=1780e3cc3bb6e7514cd141e9f837bf83;v=0;_tb_token_=fb13e3ee13e77;_m_h5_tk=e38bb4bac8606d14f4e3e90d0499f94a_1656050157762;_m_h5_tk_enc=76f353efff1883eec471912a42ecc783;tfstk=cfOCBVmvikqQn3HzTegZLGZ2rC15Z9ic58j9RcpoM5T02MTCixVVccfNfkfPyN1..;l=eBMAoWzqL6O1ZKDhBOfwhurza77OGIRAguPzaNbMiOCP_gCp5jA1W6b5MMT9CnGVhsT2R3uKagAwBeYBqI2jjqjqnZ2bjbkmn;isg=BMrKoAG5nLBFjxABGbp50JlLG7Bsu04VAQVWEFQDG52oB2rBPEsiJUJxF3Pb98at',
    'referer':'https://www.taobao.com/',
    'sec-ch-ua': ' "Not A;Brand";v="99", "Chromium";v="102", "Microsoft Edge";v="102"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'script',
    'sec-fetch-mode': 'no-cors',
    'sec-fetch-site': 'same-site',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44',
}
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
content = content.split('(')[1].split(')')[0]
with open('./file/jsonpath解析淘票票.json','w',encoding='utf-8')as fp:
    fp.write(content)
import json
import jsonpath
obj = json.load(open('./file/jsonpath解析淘票票.json','r',encoding='utf-8'))
cith_list = jsonpath.jsonpath(obj,'$..regionName')
print(cith_list)

在这里插入图片描述

四、BeautifulSoup的基本使用

简称:bs4
是啥:BeautifulSoup和lxml一样,是一个html解析器,主要功能是解析和提取数据
优点:接口设计人性化,使用方便
缺点:效率没有lxml高

【使用步骤】

  1. 安装 pip install bs4 -i https://pypi.douban.com/simple
  2. 导入 from bs4 import BeautifulSoup
  3. 创建服务对象
    (1)服务器响应的文件生成对象
    soup = BeautifulSoup(response.read().decode(),'lxml')
    (2)本地文件生成对象
    soup = BeautifulSoup(open('1.html'),'lxml')
    注意:默认打开文件的编码格式是gbk所以需要指定打开的编码格式

案例:

# 1.通过解析本地文件,掌握bs4的基础语法
# 默认打开文件的编码格式是gbk,所以需要打开文件时指定编码格式
soup = BeautifulSoup(open('file/bs4解析本地文件.html',encoding='utf-8'),'lxml')
# 1.根据标签名查找结点
print(soup.a)  # 找到第一个符合条件的数据
print(soup.a.attrs) # 获取标签的属性和属性值
# bs4的一些函数
# (1)find
# 返回的是第一个符合条件的数据
print(soup.find('a'))
# 根据title的值找到对应的标签对象
print(soup.find('a',title='a2'))
# 根据class的值找到对应的标签对象 class下需要添加下划线
print(soup.find('a',class_ = 'a1'))
# (2)find_all 返回的是一个列表,并且返回了所有的a标签
print(soup.find_all('a'))
# 若想获取多个标签的数据,需要在find_all的参数中添加列表元素
print(soup.find_all(['a','span']))
# limitc查找前几个数据
print(soup.find_all('li',limit=2))
# (3)select (推荐)
# select方法返回的是一个列表,并且返回多个数据
print(soup.select('a'))
# 可以通过.代表class,把该操作叫做类选择器
print(soup.select('.a1'))

print(soup.select('#l1'))

# 属性选择器 查找到li标签中有id的标签
print(soup.select('li[id]'))
# 查找到li标签中id = l2 的标签
print(soup.select('li[id="l2"]'))

# 层级选择器
# 后代选择器  找到div下面的li
print(soup.select('div li'))
# 子代选择器  某标签的第一级子标签  在bs4中加不加空格都可以
print(soup.select('div > ul > li'))

# 找到a和li标签的所有对象
print(soup.select('a,li'))

节点信息 获取节点内容

obj = soup.select('#d1')[0]
# 如果标签对象中只有内容,则string 和get_text()都可以获取到内容
# 如果标签对象中除了内容还有标签,则string获取不到数据,而get_text()可以获取数据
# 一般情况下,推荐使用get_text()
 print(obj.string)
 print(obj.get_text())
# 节点的属性
# 为啥要加[0],由于select返回的是列表。列表是没有select属性的
obj = soup.select('#p1')[0]
# name是标签的名字
print(obj.name)
# 将属性值作为一个字典返回
print(obj.attrs)

# 获取节点的属性
obj = soup.select('#p1')[0]
print(obj.attrs.get('class'))
print(obj.get('class'))
print(obj['class'])

五、BeautifulSoup爬取星巴克数据

XPath插件打开快捷键:ctrl+shift+X

import urllib.request
url = 'https://www.starbucks.com.cn/menu/'
response = urllib.request.urlopen(url)
content = response.read().decode('utf-8')
from bs4 import BeautifulSoup
soup = BeautifulSoup(content,'lxml')
# //ul[@class='grid padded-3 product']//strong/text()
name_list = soup.select('ul[class = "grid padded-3 product"] strong')
for name in name_list :
    print(name.get_text())

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45556665/article/details/125435594