Python网络爬虫(1):静态网页抓取

Python网络爬虫(1):静态网页抓取

文章目录

    • Python网络爬虫(1):静态网页抓取
      • 前言
      • 1 安装Requests
      • 2 获取响应内容
      • 3 定制Requests
        • 3.1 传递URL参数`params`
        • 3.2 定制请求头`headers`
        • 3.3 发送POST请求`data`
        • 3.4 超时`timeout`
      • 4 requests爬虫实践:豆瓣TOP250电影数据

前言

在网站设计中,纯粹HTML格式的网页通常被称为静态网页,早期的网站一般都是由静态网页制作的。
在网络爬虫中,静态网页的数据比较容易获取,因为所有数据都呈现在网页的HTML代码中。
相对而言,使用AJAX动态加载网页的数据不一定会出现在HTML代码中,这就给爬虫增加了困难。
在静态网页抓取中,有一个强大的Requests库能够让你轻易地发送HTTP请求。这篇文章主要介绍如何使用Requests库获取响应内容,最后可以通过定制Requests的一些参数来满足我们的需求。

1 安装Requests

pip install requests

2 获取响应内容

import requests
r=requests.get('http://www.santostang.com/')
print("文本编码:", r.encoding)
print("响应状态码:", r.status_code)
print("字符串方式的响应体:", r.text)
print('字节方式的响应体:', r.content)
print('Request中内置的JSON解码器', r.json())

输出:

本编码: UTF-8
响应状态码: 200
字符串方式的响应体: <!DOCTYPE html>...
  • 说明
    (1)r.encoding是服务器内容使用的文本编码。
    (2)r.status_code用于检测响应的状态码,如果返回200,就表示请求成功了;如果返回的是4xx,就表示客户端错误;返回5xx则表示服务器错误响应。我们可以用r.status_code来检测请求是否正确响应。
    (3)r.text是服务器响应的内容,会自动根据响应头部的字符编码进行解码。
    (4)r.content是字节方式的响应体,会自动解码gzipdeflate编码的响应数据。
    (5)r.json()Requests中内置的JSON解码器

3 定制Requests

有些网页需要对Requests的参数进行设置才能获取需要的数据,这包括传递URL参数params定制请求头headers发送POST请求data设置超时timeout 等。

3.1 传递URL参数params

  • 请求特定的数据,我们需要在URL的查询字符串中加入某些数据

如:http://httpbin.org/get?key1=value1&key2=value2

  • 在Requests中,你可以直接把这些参数保存在字典中,用params构建至URL中。

例如,传递key1=value1key2=value2http://httpbin.org/get,可以这样编写:

import requests

key_dict = {
     'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://httpbin.org/get', params=key_dict)
print('URL已经正确编码:', r.url)
print("文本编码:", r.encoding)
print("响应状态码:", r.status_code)
print('字符串方式的响应体:\n', r.text)

输出:

URL已经正确编码: http://httpbin.org/get?key1=value1&key2=value2
文本编码: utf-8
响应状态码: 200
字符串方式的响应体:
 {
     
  "args": {
                      # 使用get请求,此处的args的key1,key2值会被显示出来
    "key1": "value1",
    "key2": "value2"
  }, 
  "headers": {
     
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.25.1", 
    "X-Amzn-Trace-Id": "Root=1-6026482c-41a9bd646c22ba00497a8a63"
  }, 
  "origin": "118.212.203.240", 
  "url": "http://httpbin.org/get?key1=value1&key2=value2"
}

3.2 定制请求头headers

请求头Headers提供了关于请求、响应或其他发送实体的信息。
对于爬虫而言,请求头十分重要,如果没有指定请求头或请求的请求头和实际网页不一致,就可能无法返回正确的结果。
Requests并不会基于定制的请求头Headers的具体情况改变自己的行为,只是在最后的请求中,所有的请求头信息都会被传递进去

import requests

# key_dict = {'key1': 'value1', 'key2': 'value2'}
# 指定请求头
headers = {
     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63',
           'Host': 'www.santostang.com'}

# r = requests.get('http://httpbin.org/get', params=key_dict)
r = requests.get('http://www.santostang.com/', headers=headers)

print('URL已经正确编码:', r.url)
print("文本编码:", r.encoding)
print("响应状态码:", r.status_code)
print('字符串方式的响应体:\n', r.text)

输出:

URL已经正确编码: http://www.santostang.com/
文本编码: UTF-8
响应状态码: 200

3.3 发送POST请求data

除了GET请求外,有时还需要发送一些编码为表单形式的数据,如在登录的时候请求就为POST,因为如果用GET请求,密码就会显示在URL,这是非常不安全的。
如果要实现POST请求,只需要简单地传递一个字典给Requests中的data参数,这个数据字典就会在发出请求的时候自动编码为表单形式

import requests

key_dict = {
     'key': 'value1', 'key2': 'value2'}

r = requests.post('http://httpbin.org/post', data=key_dict)

print('URL已经正确编码:', r.url)
print("文本编码:", r.encoding)
print("响应状态码:", r.status_code)
print('字符串方式的响应体:\n', r.text)

输出:

URL已经正确编码: http://httpbin.org/post
文本编码: utf-8
响应状态码: 200
字符串方式的响应体:
 {
     
  "args": {
     }, # 使用post请求,此处的args的key1,key2值会被隐藏
  "data": "", 
  "files": {
     }, 
  "form": {
        # form变量的值为key_dict输入的值
    "key": "value1", 
    "key2": "value2"
  }, 
  "headers": {
     
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "22", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.25.1", 
    "X-Amzn-Trace-Id": "Root=1-60264cca-63d77c2c1c8bcf8c1042057b"
  }, 
  "json": null, 
  "origin": "118.212.203.240", 
  "url": "http://httpbin.org/post"
}

3.4 超时timeout

有时爬虫会遇到服务器长时间不返回,这时爬虫程序就会一直等待,造成爬虫程序没有顺利地执行。
因此,可以用Requeststimeout参数设定的秒数结束之后停止等待响应。
意思就是,如果服务器在timeout秒内没有应答,就返回异常。一般会把这个值设置为20秒。

4 requests爬虫实践:豆瓣TOP250电影数据

静态网页抓取实践项目的目的是获取豆瓣电影TOP250的所有电影的名称,网页地址为:https://movie.douban.com/top250。在此爬虫中,将请求头定制为实际浏览器的请求头。

#! /usr/bin/python
# coding: UTF-8

import requests
from bs4 import BeautifulSoup

def get_movies():
    # 定制请求头 requests
    headers = {
     
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63',
        'Host': 'movie.douban.com'}

    movie_list = []

    # 1页25部电影,for循环获取250部
    for i in range(0, 10):
        link = 'https://movie.douban.com/top250?start=' + str(i*25)

        # 发送get请求,设置超时 timeout
        r = requests.get(link, headers=headers, timeout=10)

        print('================================================================================================================')
        # 检验状态
        print(str(i+1), ' 页响应状态码:', r.status_code)
        print('URL已经正确编码:', r.url)
        print("文本编码:", r.encoding)
        # print(r.text)   # r.text里的内容为html文本形式

        # 解析网页
        soup = BeautifulSoup(r.text, 'lxml')
        div_list = soup.find_all('div', class_='hd')
        # div_info_list = soup.find_all('div', class_='item')

        # 把电影名保存到movie_list列表中
        for each in div_list:
            movieName = each.a.span.text.strip()
            movie_list.append(movieName)    # 把电影都保存到字典后,由下边的打印语句打印出总的list

    print(movie_list)
    return movie_list

# 调用函数
movies = get_movies()

输出如图:
Python网络爬虫(1):静态网页抓取_第1张图片

你可能感兴趣的:(Python,网络爬虫,python,网络)