【爬虫】3.4 爬取网站复杂数据

1. Web服务器网站

进一步把前面的Web网站的mysql.html, python.html, java.html丰富其中 的内容,并加上图形:

mysql.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>mysql</title>
</head>
<body><h3>MySQL数据库</h3><div>MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗 下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是 最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软 件。</div><div><img src="mysql.jpg"  /></div><a href="books.html">Home</a>
</body>
</html>

java.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>java</title>
</head>
<body><h3>Java程序设计</h3><div>Java是一门面向对象编程语言,不仅吸收了C++语言的各种优 点,还摒弃了C++里难以理解的多继承、指针等概念,因此 Java语言具有功能强大和简单易用两个特征。Java语言作为静 态面向对象编程语言的代表,极好地实现了面向对象理论,允 许程序员以优雅的思维方式进行复杂的编程.</div><div><img src="java.jpg"></div><a href="books.html">Home</a>
</body>
</html>

python.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>python</title>
</head>
<body><h3>Python程序设计</h3><div>Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一 种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年。</div><div><img src="python.jpg"></div><a href="books.html">Home</a>
</body>
</html>

2. 爬取网站的复杂数据

服务器server.py程序还是前面3.2的,如下:

import flask
import osapp = flask.Flask(__name__)def getFile(fileName):data = b""if os.path.exists(fileName):fobj = open(fileName, "rb")data = fobj.read()fobj.close()return data@app.route("/")
def index():return getFile("books.html")@app.route("/<section>")
def process(section):data = ""if section != "":data = getFile(section)return dataif __name__ == "__main__":app.run()

        爬取网站中的mysql, python, java的简介与图像。我们看到简介在网页的第一个<div>中,图像在<img>中,而且只有这3个网页有这样的特征,

设计客户端client.py程序如下:

from bs4 import BeautifulSoup
import urllib.requestdef spider(url):global urlsif url not in urls:urls.append(url)try:data = urllib.request.urlopen(url)data = data.read().decode()soup = BeautifulSoup(data, "lxml")print(soup.find("h3").text)divs = soup.select("div")imgs = soup.select("img")# 判断这个url页面是否有<div>与<img>,如果有就获取第一个<div>的文字,下载第一个<img>的图像if len(divs) > 0 and len(imgs) > 0:print(divs[0].text)url = start_url + "/" + imgs[0]["src"]urllib.request.urlretrieve(url, "downloaded-" + imgs[0]["src"])print("download-", imgs[0]["src"])links = soup.select("a")for link in links:href = link["href"]url = start_url + "/" + hrefspider(url)except Exception as err:print(err)start_url = "http://127.0.0.1:5000"
urls = []
spider(start_url)
print("The End")

运行结果如下:

 程序执行完毕后还看到下载了3个文件:

"downloaded-mysql.jpg"、 "downloadedpython.jpg"、"downloaded-java.jpg"

3. 爬取程序的改进

(1)服务器程序

        由于我们的web网站时本地的,因此下载图像非常快,而实际应用中 Web网站是远程的一个服务器,由于网络原因可能下载会比较慢。为了 模拟这个过程,

改进后的服务器serverUpdate.py程序如下:

import flask
import os
import random
import timeapp = flask.Flask(__name__)def getFile(fileName):data = b""if os.path.exists(fileName):fobj = open(fileName, "rb")data = fobj.read()fobj.close()# 随机等待1-10秒time.sleep(random.randint(1, 10))return data@app.route("/")
def index():return getFile("books.html")@app.route("/<section>")
def process(section):data = ""if section != "":data = getFile(section)return dataif __name__ == "__main__":app.run()

        该程序在每次返回一个网页或者图像的函数getFile中都随机等待了1- 10秒,这个过程十分类似网络条件较差的情景,即访问任何一个网页或 者图像都有1-10秒的延迟。

(2)客户端程序

        从目前的程序来看这个程序在下载一个图像时是等待的,如果这个图像很大,那么下载时间很长,程序就必须一直等待,其它网页就无法继续访问,即卡死在一个网页的图像下载处。为了避免这个问题,一般可以对程序做以下改进:

  • 设置urllib.request下载图像的时间,如果超过一定时间还没有完 成下载就放弃;
  • 设置下载过程是一个与主线程不同的子线程,子线程完成下载 任务,不影响主线程继续访问别的网页。        

改进后的客户端clientUpdate.py程序如下:

from bs4 import BeautifulSoup
import urllib.request
import threadingdef download(url, fileName):try:# 设置下载时间最长100秒data = urllib.request.urlopen(url, timeout=100)data = data.read()fobj = open("download" + fileName, "wb")fobj.write(data)fobj.close()print("download", fileName)except Exception as err:print(err)def spider(url):global urlsif url not in urls:urls.append(url)try:data = urllib.request.urlopen(url)data = data.read().decode()soup = BeautifulSoup(data, "lxml")print(soup.find("h3").text)links = soup.select("a")divs = soup.select("div")imgs = soup.select("img")# 判断这个url页面是否有<div>与<img>,如果有就获取第一个<div>的文字,下载第一个<img>的图像if len(divs) > 0 and len(imgs) > 0:print(divs[0].text)url = start_url + "/" + imgs[0]["src"]# 启动一个下载线程下载图像T = threading.Thread(target=download, args=(url, imgs[0]["src"]))T.setDaemon(False)T.start()threads.append(T)for link in links:href = link["href"]url = start_url + "/" + hrefspider(url)except Exception as err:print(err)start_url = "http://127.0.0.1:5000"
urls = []
threads = []
spider(start_url)
# 等待所有线程执行完毕
for t in threads:t.join()
print("The End")

执行结果如下:

 从结果看到访问java.htm网页后没有及时完成java.jpg的下载,java.jpg是在访问 network.htm网页后才完成下载的,这就是多线程的过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/81.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rabbitmq第二课-RabbitMQ核心编程模型以及消息应用场景详解

一、回顾RabbitMQ基础概念 二、RabbitMQ基础编程模型 使用RabbitMQ提供的原生客户端API进行交互。这是使用RabbitMQ的基础。 1.1、maven依赖 <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version&g…

2023考研一战上岸 电子科技大学 860软件工程 经验分享

目录 1. 前言&#xff1a;考研&#xff0c;心态最重要&#xff01; 2. 初试各科复习经验 (1) 数学一 (2) 英语一 (3) 专业课 (4) 政治 (5) 四门课时间划分 3. 复试流程和备考建议 (1) 复试流程 (2) 备考建议 4. 结语 首先&#xff0c;先简要做一个自我介绍&#xff…

墨迹api实现天气预测

文章目录 需求背景解决效果接口地址index.vueweather.vue图标文件 视频效果 需求背景 使用墨迹天气api实现天气预报&#xff0c;空气质量预报功能 解决效果 接口地址 墨迹天气 index.vue <template><div class"dqhjjc-wrap"><div class"fir…

知易行难!项目推进的6大常见问题

项目推进是一项企业发展业务中的关键任务。然而&#xff0c;许多项目在实施过程中遇到各种困难和挑战&#xff0c;导致项目无法按计划进行或无法实现预期的成果。以下是项目推进过程中常见的六个问题以及解决方案。1、项目目标不明确 项目推进时&#xff0c;如果项目团队不清楚…

Linux学习之以openresty为例学习源码安装软件

https://github.com/openresty/openresty/tags里边有openresty各个版本的源码。 https://openresty.org/en/是官网。 wget https://github.com/openresty/openresty/archive/refs/tags/v1.15.8.1.tar.gz(github网址)或者wget https://openresty.org/download/openresty-1.15.…

Redis五种数据结构底层编码结构

RedisObject Redis中的任意数据类型的键和值都会被封装为一个RedisObject&#xff0c;也叫做Redis对象&#xff0c;源码如下&#xff1a; 对象头不包含数据就已经占16字节&#xff0c;如果数据存string型&#xff0c;一个string一个对象头比较浪费空间&#xff0c;存大量数据…

Kafka系列之:对源连接器的的Exactly-Once支持

Kafka系列之&#xff1a;对源连接器的的Exactly-Once支持 一、背景二、目标三、公共接口四、连接器 API 扩展五、REST API验证六、新指标七、计划变更八、任务计数记录九、重新平衡的准备十、源任务启动十一、领导者访问配置主题十二、用于隔离事务生产者的管理 API十三、解决了…

python 加速(1)

文章目录 简单步骤像Python一样做torch 的一切安装Cmake安装 Torch &#xff08;GPU&#xff09;CMakeLists.txt试用小样设置 CLion 环境 Cuda配置VS C 环境建上手的文件step1: interpolation.cppstep2: interpolation_kernel.custep3: include/ utils.hstep4: setup.pystep5: …

redis和mysql

文章目录 一、redis1.1 redis的数据结构都有哪些&#xff1f;1.2 持久化方式有哪些&#xff1f;1.3 怎么保证缓存和数据库数据的一致性?1.4 redis缓存是什么意思&#xff1f; 二、数据库2.1 基本数据类型2.2 MySQL 的内连接、左连接、右连接有什么区别?2.3 MySQL 问题排查都有…

闲置iPad Pro打造真正的生产力工具!使用vscode编程写代码

文章目录 前言视频教程1. 本地环境配置2. 内网穿透2.1 安装cpolar内网穿透(支持一键自动安装脚本)2.2 创建HTTP隧道 3. 测试远程访问4. 配置固定二级子域名4.1 保留二级子域名4.2 配置二级子域名 5. 测试使用固定二级子域名远程访问6. iPad通过软件远程vscode6.1 创建TCP隧道 7…

Java阶段四Day08

Java阶段四Day08 文章目录 Java阶段四Day08关于pom.xml中的版本关于Session关于Token关于JWT在项目中使用JWTCustomUserDetailsUserDetailServiceImplUserServiceImpl 关于pom.xml中的版本 查看<groupId> 是同一家的只需配一个版本号<version><artifactId>中…

Spring Boot中的Profile:原理、用法与示例

Spring Boot中的Profile&#xff1a;原理、用法与示例 前言 Spring Boot 是一个快速开发 Spring 应用程序的框架&#xff0c;它提供了很多有用的功能和特性。其中&#xff0c;Profile 是一个常用的功能&#xff0c;它可以根据不同的环境配置来加载不同的配置文件&#xff0c;…