Python 爬虫技术 第06节 HTTP协议与Web基础知识

打印 上一主题 下一主题

主题 546|帖子 546|积分 1638

HTTP(Hypertext Transfer Protocol)是用于从Web服务器传输超文本到当地浏览器的传输协议。它是互联网上应用最为广泛的一种网络协议,几乎全部的网页数据都是通过HTTP协议进行传输的。下面,我将联合一个简单的Python案例来详细解说HTTP协议与Web基础知识。
HTTP协议基础

哀求与响应模子

HTTP遵循哀求/响应模子。客户端(通常是浏览器)发送一个HTTP哀求到服务器,服务器收到哀求后,会返回一个HTTP响应。
哀求结构

一个典型的HTTP哀求由三部分构成:

  • 哀求行 - 包含方法(GET, POST, PUT, DELETE等)、资源的URL和使用的HTTP版本。
  • 哀求头 - 包含客户端信息、认证信息、编码偏好、缓存控制等。
  • 哀求体 - 在POST、PUT等哀求中,包含要发送的数据。
响应结构

HTTP响应也由三部分构成:

  • 状态行 - 包括HTTP版本、状态码和形貌状态的短语。
  • 响应头 - 包含服务器信息、缓存控制、日期时间、内容类型等。
  • 响应体 - 现实的响应数据,比方HTML文档、图片、视频等。
Python案例:使用http.client模块发送HTTP哀求

http.client是Python尺度库的一部分,提供了发送HTTP哀求的功能。下面是一个使用http.client发送GET哀求的例子:
  1. import http.client
  2. import json
  3. # 定义主机和端口
  4. host = "www.example.com"
  5. port = 80
  6. # 创建连接
  7. conn = http.client.HTTPConnection(host, port)
  8. # 发送GET请求
  9. conn.request("GET", "/")
  10. # 获取响应
  11. response = conn.getresponse()
  12. # 打印状态码
  13. print("Status:", response.status, response.reason)
  14. # 读取响应数据
  15. data = response.read().decode()
  16. # 打印响应数据
  17. print("Data:\n", data)
  18. # 关闭连接
  19. conn.close()
复制代码
Python案例:使用requests库发送HTTP哀求

requests库是一个非常流行的第三方库,用于发送HTTP哀求。它比http.client更高级,更易用,支持更多功能。
  1. import requests
  2. # 发送GET请求
  3. response = requests.get("http://www.example.com")
  4. # 检查响应状态码
  5. if response.status_code == 200:
  6.     # 打印响应内容
  7.     print(response.text)
  8. else:
  9.     print("Request failed with status code:", response.status_code)
复制代码
Python案例:使用Flask框架创建Web服务器

Flask是一个轻量级的Web框架,非常得当用于构建小型Web应用程序或API服务。下面是一个简单的Flask应用示例:
  1. from flask import Flask
  2. app = Flask(__name__)
  3. @app.route('/')
  4. def home():
  5.     return "Hello, World!"
  6. if __name__ == '__main__':
  7.     app.run(debug=True)
复制代码
在这个例子中,我们创建了一个简单的Web服务器,它监听全部外部接口上的默认端口(5000),并在接收到哀求时返回"Hello, World!"的消息。
总结

HTTP协议是Web通讯的基础,明白其工作原理对于开发Web应用程序至关重要。Python提供了多种工具和库来处理HTTP哀求和响应,无论是客户端还是服务器端编程,都可以轻松实现。通过上述案例,你应该能够开始编写自己的HTTP客户端和服务器代码了。
当我们谈论扩展基于HTTP的Python代码时,可以考虑增加的功能有很多。这里,我将展示如何使用requests库来发送更复杂的HTTP哀求(如POST哀求),以及如何使用Flask框架来处理这些哀求。
使用requests发送POST哀求

假设我们有一个Web服务,它期望接收JSON格式的数据并通过POST哀求发送。下面是如何使用requests库发送如许一个哀求:
  1. import requests
  2. import json
  3. url = "http://localhost:5000/data"  # 假设这是你的Flask应用的URL
  4. data = {
  5.     "name": "John Doe",
  6.     "age": 30,
  7.     "city": "New York"
  8. }
  9. headers = {'Content-Type': 'application/json'}
  10. response = requests.post(url, data=json.dumps(data), headers=headers)
  11. if response.status_code == 200:
  12.     print("Request successful!")
  13.     print("Response:", response.json())
  14. else:
  15.     print("Request failed with status code:", response.status_code)
复制代码
使用Flask接收POST哀求

接下来,我们将在Flask应用中添加一个端点来接收上述POST哀求:
  1. from flask import Flask, request, jsonify
  2. app = Flask(__name__)
  3. @app.route('/data', methods=['POST'])
  4. def receive_data():
  5.     if request.headers['Content-Type'] == 'application/json':
  6.         data = request.json
  7.         print("Received data:", data)
  8.         # 这里可以处理数据,例如保存到数据库
  9.         return jsonify({"message": "Data received successfully"}), 200
  10.     else:
  11.         return jsonify({"error": "Invalid content type"}), 400
  12. if __name__ == '__main__':
  13.     app.run(debug=True)
复制代码
扩展Flask应用

我们还可以为Flask应用添加更多的路由和功能。比方,添加一个GET哀求来获取数据:
  1. @app.route('/data', methods=['GET'])
  2. def get_data():
  3.     # 假设这里有从数据库获取数据的逻辑
  4.     data = {"name": "John Doe", "age": 30, "city": "New York"}
  5.     return jsonify(data), 200
复制代码
错误处理

在Flask中,可以使用错误处理器来处理各种HTTP错误:
  1. @app.errorhandler(404)
  2. def page_not_found(e):
  3.     return jsonify({"error": "Resource not found"}), 404
  4. @app.errorhandler(500)
  5. def internal_server_error(e):
  6.     return jsonify({"error": "Internal server error"}), 500
复制代码
使用环境变量和设置

为了提高安全性,可以使用环境变量来管理敏感信息,如数据库URL、API密钥等:
  1. import os
  2. app.config['DATABASE_URL'] = os.getenv('DATABASE_URL')
复制代码
然后,在摆设环境中设置这些环境变量:
  1. export DATABASE_URL=postgres://user:pass@localhost/dbname
复制代码
使用Flask扩展

Flask有很多扩展,可以简化常见的任务,如数据库集成、身份验证、表单处理等。比方,使用Flask-SQLAlchemy来集成SQLAlchemy ORM:
  1. from flask_sqlalchemy import SQLAlchemy
  2. db = SQLAlchemy(app)
  3. class User(db.Model):
  4.     id = db.Column(db.Integer, primary_key=True)
  5.     username = db.Column(db.String(80), unique=True, nullable=False)
  6.     email = db.Column(db.String(120), unique=True, nullable=False)
  7.    
  8.     def __repr__(self):
  9.         return '<User %r>' % self.username
复制代码
通过这些扩展和加强功能,你可以构建功能丰富且安全的Web应用程序。这只是一个开始,现实的应用大概涉及更复杂的业务逻辑、安全措施、性能优化和摆设策略。
既然我们已经讨论了如何使用requests库来发送POST哀求和使用Flask框架来接收和处理这些哀求,我们可以进一步美满代码,使其更具实用性。以下是几个方面的扩展:

  • 数据库集成:使用Flask-SQLAlchemy来长期化数据。
  • 身份验证:使用Flask-Login或Flask-JWT来管理用户身份验证。
  • 表单验证:使用WTForms来处理和验证表单数据。
  • 日志记录:使用logging模块来记录重要事件和错误。
  • 单元测试:使用pytest来编写和运行单元测试。
起首,让我们继承使用Flask-SQLAlchemy来管理用户数据:
安装Flask-SQLAlchemy

在终端中安装Flask-SQLAlchemy:
  1. pip install Flask-SQLAlchemy
复制代码
设置Flask-SQLAlchemy

在Flask应用中添加数据库设置:
  1. from flask import Flask
  2. from flask_sqlalchemy import SQLAlchemy
  3. app = Flask(__name__)
  4. app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'  # 或者使用其他数据库
  5. app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
  6. db = SQLAlchemy(app)
复制代码
创建数据库模子

界说一个用户模子:
  1. class User(db.Model):
  2.     id = db.Column(db.Integer, primary_key=True)
  3.     name = db.Column(db.String(80), nullable=False)
  4.     age = db.Column(db.Integer)
  5.     city = db.Column(db.String(120))
  6.     def __repr__(self):
  7.         return f'<User {self.name}>'
复制代码
创建数据库表

在应用运行前创建数据库表:
  1. if __name__ == '__main__':
  2.     db.create_all()
  3.     app.run(debug=True)
复制代码
修改POST路由以保存数据

更新receive_data函数以将数据保存到数据库:
  1. @app.route('/data', methods=['POST'])
  2. def receive_data():
  3.     if request.headers['Content-Type'] == 'application/json':
  4.         data = request.json
  5.         new_user = User(name=data['name'], age=data['age'], city=data['city'])
  6.         db.session.add(new_user)
  7.         db.session.commit()
  8.         return jsonify({"message": "Data received and saved successfully"}), 201
  9.     else:
  10.         return jsonify({"error": "Invalid content type"}), 400
复制代码
添加GET路由以查询数据

添加一个路由来查询全部用户数据:
  1. @app.route('/data', methods=['GET'])
  2. def get_data():
  3.     users = User.query.all()
  4.     return jsonify([user.to_dict() for user in users]), 200
复制代码
界说to_dict方法

在User类中添加一个方法来方便地将对象转换为字典:
  1. class User(db.Model):
  2.     # ...
  3.    
  4.     def to_dict(self):
  5.         return {
  6.             'id': self.id,
  7.             'name': self.name,
  8.             'age': self.age,
  9.             'city': self.city
  10.         }
复制代码
日志记录

使用Python的logging模块记录关键操作:
  1. import logging
  2. logging.basicConfig(level=logging.INFO)
  3. logger = logging.getLogger(__name__)
  4. @app.route('/data', methods=['POST'])
  5. def receive_data():
  6.     # ...
  7.     logger.info(f"New user data received: {data}")
  8.     # ...
复制代码
单元测试

使用pytest编写单元测试:
  1. # tests/test_app.py
  2. import pytest
  3. from app import app, db
  4. from app.models import User
  5. @pytest.fixture
  6. def client():
  7.     app.config['TESTING'] = True
  8.     client = app.test_client()
  9.     with app.app_context():
  10.         db.create_all()
  11.     yield client
  12.     with app.app_context():
  13.         db.drop_all()
  14. def test_receive_data(client):
  15.     response = client.post('/data', json={
  16.         "name": "Test User",
  17.         "age": 25,
  18.         "city": "Test City"
  19.     }, content_type='application/json')
  20.     assert response.status_code == 201
  21.     assert User.query.count() == 1
复制代码
以上步调将使你的应用更加健壮和实用,但请记住,现实摆设时大概必要考虑更多的细节,比方生产环境下的数据库设置、安全性、性能优化等。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

羊蹓狼

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表