python爬虫学习

安装需求

  • Python 环境

  • 爬虫相关Python 第三方库

第三方库安装

  • requests

 pip install requests

 

  • 该模块用于请求网页,是爬虫必备模块

爬取目标分析

  • 浏览网页源码,分析网页结构

 

  • 具体到每张图片元素的url,都嵌在<div class="grid ">标签下

  • 而在图片的详情页中我们还可以发现这个网站本身就提供了下载链接,就是在这个详情页的url后面加上/download,但是爬虫不是靠这个运行的,我们接下来找到的是这里

 

  • 这一段里.jpg就十分明显,但是后面还有一段限制长宽像素的我们在爬取的时候应该删去,否则只会爬到一些缩略图,而不是原图

结构构造

 import requests
 ​
 # 抓取函数
 def main():
     pass
 ​
 # 解析函数
 def format():
     pass
 ​
 # 存储函数
 def save_image():
     pass
 ​
 if __name__ == '__main__':
     main()

抓取语句构造

 def main():
     url = "https://burst.shopify.com/photos"
     headers = {
         "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
     }
     res = requests.get(url=url, headers=headers, timeout=5)
     print(res.text)
  • 这条抓取语句抓取的是整个网页的源码,抓下来以后才可以进行下一步解析源码,取得存在图片的url

  • 这里的headers配置是为了在请求网页时将爬虫的请求伪造成貌似正常的访问请求,防止图片下载失败

解析语句构造

  • 通过教程我学习了直接字符串拼接配合正则表达式来获取到图片详情页地址

  • 前面我们已经对访问网页上图片的逻辑进行过分析,所以第一步就是拆解字符串,取出目标数据部分,让爬虫获取各个分页中的各个图片的url

 def format(text):
     # 处理字符串
     div_html = '<div class="grid ">'
     page_html = '<section class="section section--tight section--padding-top-only">'
     start = text.find(div_html) + len(div_html)
     end = text.find(page_html)
     origin_text = text[start:end]
     return origin_text
     pass
  • 在这各部分截取了从'<div class="grid ">'到'<section class="section section--tight section--padding-top-only">'的所有源码,其中很多都是对爬虫来说无用的,所以我们还要用正则表达式筛选一遍,括号的作用也是形成列表为了后续方便提取。

 import re 
 ​
 def format(text):
     # 处理字符串
     div_html = '<div class="grid ">'
     page_html = '<section class="section section--tight section--padding-top-only">'
     start = text.find(div_html) + len(div_html)
     end = text.find(page_html)
     origin_text = text[start:end]
     # 正则表达式筛选
     pattern = re.compile('href="(.*?)"')
     hrefs = pattern.findall(origin_text)
     return hrefs
  • 使用的技术是 re 模块,

    re.compile('href="(.*?)"')

  • 这一段用正则表达式匹配了所有在href后面的字符串

  • 和前面的抓取语句的代码相结合运行一遍看看

 

  • 除了我们需要的'/photos/person-stands-on-rocks-poking-out-of-the-ocean-shoreline'这样的字符之外,还能看到很多不必要的字符,这里要再次进行筛选

     pattern = re.compile('href="(.*?)"')
     hrefs = pattern.findall(origin_text)
     hrefs = [i for i in hrefs if i.find("photos")>0]
  • 再运行试试

抓取内页数据

  • 已经获取了这一页的所有图片的url,下一步就是去获取这些url里的数据了

     for href in hrefs:
         url = f"https://burst.shopify.com{href}"
         headers = {
         "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
     }
         res = requests.get(url=url, headers=headers, timeout=5)
         res.encoding = "GBK"
         format_detail(res.text)
         break
 ​
 # 格式化细节
 def format_detail(text):
     # 处理字符串
     div_html = '<div class="photo__download">'
     page_html = '<div class="photo__social-shares-container">'
     start = text.find(div_html) + len(div_html)
     end = text.find(page_html)
     origin_text = text[start:end]
     pattern = re.compile('data-modal-image-url="(.*?)"')
     src = pattern.findall(origin_text)
     src = src[0]
     image_src = ''
     for i in range(0,len(src)+1):
         if src[i] != "?":
             image_src =image_src +src[i]
         if src[i] == "?":
             break
     return image_src
  • 这里处理字符串在没在教程里找到可借鉴的,就自己写了一段很垃圾的代码来处理图片url后面对图片像素的限制,是直接处理字符串得到结果

保存语句构造

  • 保存图片部分,需要提前导入 time 模块,对图片进行重命名。

 # 存储函数
 def save_image(image_src):
     res = requests.get(url=image_src, timeout=5)
     content = res.content
     with open(f"{str(time.time())}.jpg", "wb") as f:
         f.write(content)
  • 使用 requests.get 方法直接请求图片地址,调用响应对象的 content 属性,获取二进制流,然后使用 f.write 存储成图片。

第一张图测试结果

  • 桌面上的图片就是爬取结果

  • 看文件大小也是高清图片

代码优化

 import re
 import time
 import requests
 ​
 # 请求函数
 def request_get(url, ret_type="text", timeout=5):
     headers = {
         "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
     }
     res = requests.get(url=url, headers=headers, timeout=timeout)
     if ret_type == "text":
         return res.text
     elif ret_type == "image":
         return res.content
 ​
 # 抓取函数
 def main():
     urls = [f"https://burst.shopify.com/photos?page={i}" for i in range(2, 201)]
     url = "https://burst.shopify.com/photos"
     urls.insert(0, url)
     for url in urls:
         print("抓取列表页地址为:", url)
         text = request_get(url)
         format(text)
 ​
 # 解析函数
 def format(text):
     # 处理字符串
     origin_text = split_str(text, '<div class="grid ">', '<section class="section section--tight section--padding-top-only">')
     # 正则表达式筛选
     pattern = re.compile('href="(.*?)"')
     hrefs = pattern.findall(origin_text)
     hrefs = [i for i in hrefs if i.find("photos")>0]
     for href in hrefs:
         url = f"https://burst.shopify.com{href}"
         print(f"正在下载:{url}")
         text = request_get(url)
         format_detail(text)
 ​
 ​
 # 格式化细节
 def format_detail(text):
     # 处理字符串
     origin_text = split_str(text, '<div class="photo__download">', '<div class="photo__social-shares-container">')
     pattern = re.compile('data-modal-image-url="(.*?)"')
     src = pattern.findall(origin_text)
     src = src[0]
     image_src = ''
     for i in range(0,len(src)+1):
         if src[i] != "?":
             image_src =image_src +src[i]
         if src[i] == "?":
             break
     save_image(image_src)
 ​
 #字符分割
 def split_str(text, s_html, e_html):
     start = text.find(s_html) + len(e_html)
     end = text.find(e_html)
     origin_text = text[start:end]
     return origin_text
 ​
 # 存储函数
 def save_image(image_src):
     content = request_get(image_src, "image")
     with open(f"{str(time.time())}.jpg", "wb") as f:
         f.write(content)
         print("图片保存成功")
 ​
 if __name__ == '__main__':
     main()
 ​

运行结果

  • 截图的时候还在下载,下载速度慢这个问题可以做一下多线程优化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值