利用python实现查看溧阳的摄影圈

作者:??梦想橡皮擦???? 时间:2021-09-05 21:33:16 

前言:

本篇博客继续学习BeautifulSoup,目标站点选取“溧阳摄影圈”,这一地方论坛。

目标站点分析

本次要采集的目标站点分页规则如下:

http://www.jsly001.com/thread-htm-fid-45-page-{页码}.html

代码采用多线程 threading 模块+requests 模块+BeautifulSoup 模块编写。

采取规则依据列表页 → 详情页:

利用python实现查看溧阳的摄影圈

溧阳摄影圈图片采集代码

本案例属于实操案例,先展示完整代码,然后基于注释与重点函数进行说明。

主要实现步骤如下所示:

  • 设置日志输出级别

  • 声明一个 LiYang 类,其继承自 threading.Thread

  • 实例化多线程对象

  • 每个线程都去获取全局资源

  • 调用html解析函数

  • 获取板块主题分割区域,主要为防止获取置顶的主题

  • 使用 lxml 进行解析

  • 解析出标题与数据

  • 解析图片地址

  • 保存图片

import random
import threading
import logging
from bs4 import BeautifulSoup
import requests
import lxml
logging.basicConfig(level=logging.NOTSET) # 设置日志输出级别
# 声明一个 LiYang 类,其继承自 threading.Thread
class LiYangThread(threading.Thread):
   def __init__(self):
       threading.Thread.__init__(self) # 实例化多线程对象
       self._headers = self._get_headers() # 随机获取 ua
       self._timeout = 5 # 设置超时时间

# 每个线程都去获取全局资源
   def run(self):
       # while True: # 此处为多线程开启位置
       try:
           res = requests.get(url="http://www.jsly001.com/thread-htm-fid-45-page-1.html", headers=self._headers,
                              timeout=self._timeout) # 测试获取第一页数据
       except Exception as e:
           logging.error(e)
       if res is not None:
           html_text = res.text
           self._format_html(html_text) # 调用html解析函数

def _format_html(self, html):
       # 使用 lxml 进行解析
       soup = BeautifulSoup(html, 'lxml')

# 获取板块主题分割区域,主要为防止获取置顶的主题
       part_tr = soup.find(attrs={'class': 'bbs_tr4'})

if part_tr is not None:
           items = part_tr.find_all_next(attrs={"name": "readlink"}) # 获取详情页地址
       else:
           items = soup.find_all(attrs={"name": "readlink"})
       # 解析出标题与数据
       data = [(item.text, f'http://www.jsly001.com/{item["href"]}') for item in items]
       # 进入标题内页
       for name, url in data:
           self._get_imgs(name, url)

def _get_imgs(self, name, url):
       """解析图片地址"""
       try:
           res = requests.get(url=url, headers=self._headers, timeout=self._timeout)
       except Exception as e:
           logging.error(e)
# 图片提取逻辑
       if res is not None:
           soup = BeautifulSoup(res.text, 'lxml')
           origin_div1 = soup.find(attrs={'class': 'tpc_content'})
           origin_div2 = soup.find(attrs={'class': 'imgList'})
           content = origin_div2 if origin_div2 else origin_div1

if content is not None:
               imgs = content.find_all('img')

# print([img.get("src") for img in imgs])
               self._save_img(name, imgs) # 保存图片
   def _save_img(self, name, imgs):
       """保存图片"""
       for img in imgs:
           url = img.get("src")
           if url.find('http') < 0:
               continue
           # 寻找父标签中的 id 属性
           id_ = img.find_parent('span').get("id")

try:
               res = requests.get(url=url, headers=self._headers, timeout=self._timeout)
           except Exception as e:
               logging.error(e)

if res is not None:
               name = name.replace("/", "_")
               with open(f'./imgs/{name}_{id_}.jpg', "wb+") as f: # 注意在 python 运行时目录提前创建 imgs 文件夹
                   f.write(res.content)
   def _get_headers(self):
       uas = [
           "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)",
       ]
       ua = random.choice(uas)
       headers = {
           "user-agent": ua
       }
       return headers
if __name__ == '__main__':
   my_thread = LiYangThread()
   my_thread.run()

本次案例采用中,BeautifulSoup 模块采用 lxml 解析器 对 HTML 数据进行解析,后续多采用此解析器,在使用前注意先导入 lxml 模块。

数据提取部分采用 soup.find() 与 soup.find_all() 两个函数进行,代码中还使用了 find_parent() 函数,用于采集父级标签中的 id 属性。

# 寻找父标签中的 id 属性
id_ = img.find_parent('span').get("id")

代码运行过程出现 DEBUG 信息,控制 logging 日志输出级别即可。![用python看溧阳摄影圈,里面照片非常真

来源:https://juejin.cn/post/7079963621077286925

标签:python,查看,摄影圈
0
投稿

猜你喜欢

  • 随机显示图片

    2009-07-26 10:13:00
  • MYSQL教程:my.cnf缓存优化

    2009-07-30 08:58:00
  • mysql中的mvcc 原理详解

    2024-01-18 05:10:13
  • Python中xml和json格式相互转换操作示例

    2023-04-26 18:02:39
  • 通过mysql show processlist 命令检查mysql锁的方法

    2024-01-19 22:03:11
  • JavaScript内置对象math,global功能与用法实例分析

    2024-04-22 22:36:47
  • Oracle使用触发器和mysql中使用触发器的案例比较

    2024-01-26 02:46:49
  • 如何使用分区处理MySQL的亿级数据优化

    2024-01-21 04:49:01
  • 附加到SQL2012的数据库就不能再附加到低于SQL2012的数据库版本的解决方法

    2024-01-27 19:46:16
  • 用js解决数字不能换行问题

    2024-04-23 09:25:38
  • MySQL如何统计一个数据库所有表的数据量

    2024-01-23 20:07:14
  • Python lambda 匿名函数优点和局限性深度总结

    2023-07-25 19:22:00
  • 使用Python解决常见格式图像读取nii,dicom,mhd

    2021-11-14 23:36:59
  • 使用mybatis框架连接mysql数据库的超详细步骤

    2024-01-13 06:12:08
  • AJAX应用之草稿自动保存

    2007-08-23 08:29:00
  • golang bufio包中Write方法的深入讲解

    2024-05-08 10:45:31
  • 一些sql语句

    2009-04-10 18:36:00
  • PHP面向对象程序设计高级特性详解(接口,继承,抽象类,析构,克隆等)

    2023-11-23 11:35:00
  • Python命令行click参数用法解析

    2023-07-30 14:01:20
  • php二分查找二种实现示例

    2023-11-21 00:40:13
  • asp之家 网络编程 m.aspxhome.com