python 爬虫,请求头的使用

爬虫时为啥加上请求头之后会出现错误,不加请求头可以吗,加上请求头为啥会影响def catchData()函数的使用呢

import requests
from bs4 import BeautifulSoup
import matplotlib.pyplot as plt
import bs4
import csv
def getHTMLText(url):  # 从网络上获取大学排名网页内容
    try:
        header ={'User-Agent:'
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'}
        r = requests.get(url,headers=header,timeout=30)  # 获取url信息,设定时间为30s
        r.raise_for_status()  # 产生异常信息
        r.encoding = r.apparent_encoding  # 修改编码
        return r.text  # 返回网页信息内容
    except:
        return '获取网页失败'
def catchData(ulist, html):  # 提取网页内容信息到合适的数据结构并存到一个列表里(关键部分)
    soup = BeautifulSoup(html, 'html.parser')  # 用html解析器
    for tr in soup.find('tbody').children:  # 遍历查找tbody标签且对它的孩子children做一个遍历
        if isinstance(tr, bs4.element.Tag):  # 过滤非标签类型的信息
            tds = tr('td')  # 查询tr当中的td标签并存到tds中
            ulist.append([tds[0].text.strip(), tds[1].text.strip(), tds[2].text.strip(), tds[3].text.strip(),
                          tds[4].text.strip()])  # strip()用于保留文字信息
def writeList(ulist, num, year):  # 创建一个年份+中国大学排名.csv的文件,编码方式为GBK
    f = open(year + '年中国大学排名.csv', 'w', encoding='UTF-8', newline='')
    csv_writer = csv.writer(f)
    csv_writer.writerow(['排名', '名称', '省份', '类型', '总分'])  # 写入标题:排名,名称,省份,类型,总分
    for i in range(num):  # 根据输入的写入量进行写入
        u = ulist[i]
        csv_writer.writerow([u[0], u[1], u[2], u[3], u[4]])  # 写入每条数据的前五个数据分别是:排名,名称,省份,类型,总分
    f.close()
    print(year + '年中国大学排名爬取成功')  # 打印
if __name__ == '__main__':  # 既能保证当前的.py文件直接运行也能保证其作为模块被其他.py文件导入
    for year in range(2015, 2023):  # 遍历年份
        uinfo = []
        url = 'https://www.shanghairanking.cn/rankings/bcur/' + str(year)
        html = getHTMLText(url)
        catchData(uinfo, html)
        writeList(uinfo, 10, str(year))

import csv
import xlwt
def csv_to_xlsx(year):
    with open(year+'年中国大学排名.csv', 'r', encoding='UTF-8') as f:
        read = csv.reader(f)
        workbook = xlwt.Workbook()
        sheet = workbook.add_sheet('data')  # 创建一个sheet表格
        l = 0
        for line in read:
            print(line)
            r = 0
            for i in line:
                print(i)
                sheet.write(l, r, i)  # 一个一个将单元格数据写入
                r = r + 1
            l = l + 1
        workbook.save(year+'年中国大学排名.xlsx')  # 保存Excel
if __name__ == '__main__':
    for year in range(2015,2023):
        csv_to_xlsx(str(year))



import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rcParams['font.sans-serif'] = ['STSong']#宋体
year=input("查看(2015-2022)的大学排名:")
n=str(year)
df = pd.read_csv(n+'年中国大学排名.csv', encoding='UTF-8')
x = df['总分']
y = df['名称']
x1 = np.arange(len(y))
a=int(max(x)/20)
plt.yticks(x1, y, fontsize=5)  # y轴设置为data类型的刻度
plt.xticks(range(0, int(x[0]),a ))
plt.plot(x, y, "go--", label=n+'年大学排名')
plt.title(n+"中国大学排名", fontsize=20)
for i in x1:
    plt.text(x[i], x1[i],s=str(x[i]), fontsize=20)
plt.xlabel("总分",  fontsize=18)
plt.ylabel("名称", fontsize=18)
plt.tight_layout()
plt.legend(loc="upper right")
plt.show()
'''d=pd.DataFrame(np.arange(12).reshape(3,4))
plt.plot(d)
plt.show()'''



import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.figure(facecolor='white', figsize=(10, 8))
bar_width = 0.5 # 柱子宽度
plt.rcParams['font.sans-serif'] = ['SimHei']
year = input("查看(2015-2021)的大学排名:")
n = str(year)
df = pd.read_csv(n + '年中国大学排名.csv', encoding='UTF-8')
y1 = df['总分']
y2 = df['类型']
data = df['名称']
x1 = np.arange(len(data))
a = int(max(y1) / 20)
b = int(max(y1))
plt.bar(x1, y1, bar_width, color='c', alpha=0.5)
plt.bar(x1 + bar_width, y2, bar_width, color='r', alpha=0.5)  # 柱子宽度在里面加,slpha为柱子深度
# 设置坐标轴刻度
plt.xticks(x1, data, fontsize=5)  # x轴设置为data类型的刻度
plt.yticks(range(1, b, a))
plt.grid(linestyle='--', axis='y')
plt.xlabel('(省份)名称/排名递减')
plt.ylabel('总分\n类型(综合100,理工200)')
plt.title('中国大学排名(前十)')
plt.xticks(rotation=90)
plt.tight_layout()
for a, b in zip(x1, y1):
    plt.text(a, b, b, ha='center', va='bottom', fontsize=8, color='b')
for a, b in zip(x1, y2):
    plt.text(a + bar_width, b, b, ha='center', va='bottom', fontsize=8, color='r')
plt.legend(('总分', '类型'))  # 99必须为元组
plt.show()


import re
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rcParams['font.sans-serif'] = ['STSong']  # 宋体
year = input("查看(2015-2021)的大学排名:")
n = str(year)
df = pd.read_csv(n + '年中国大学排名.csv', encoding='UTF-8')
x = df['总分']
y= df['名称']
#y=[]
#y.append(re.sub(r'[\u4e00-\u9fa5]','\n',str(s)))
a = np.arange(len(y))
plt.figure(figsize=(10, 8), dpi=100)  # 绘制一个画布,尺寸
plt.barh(a, x, linewidth=0.5, label=n + '年大学排名')  # 建立x轴坐标且为横向
for i in a:
    plt.text(x[i], a[i], s=str(x[i]))  # 增加文本
plt.yticks(a, y, fontsize=5)  # 建立y轴坐标
plt.grid(linestyle='--')  # 生成虚线网格
plt.xlabel('总分')  # x轴增加标签
plt.ylabel('名称')  # y轴增加标签
plt.title('中国大学排名前十')  # 增加标题
plt.tight_layout()
plt.legend(loc='upper right')
plt.show()  # 显示


看你这个请求头是做代理用的,不加应该也可以。有影响catchdata是因为你调用了上面方法的输出结果作为入参

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    答案:

    为了模拟正常浏览器对网页的访问,使用请求头来进行 Python 爬虫是非常必要的。如果不使用请求头,则可能会被网站识别为爬虫,并禁止访问或者返回错误内容。

    以下是一个基本的请求头示例:

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
        'Referer': 'https://www.google.com/',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'en-US,en;q=0.5',
        'Connection': 'keep-alive'
    }
    

    其中,User-Agent 是指浏览器类型和版本信息;Referer 是指当前请求的来源页面;Accept-Encoding 是指浏览器支持的压缩编码格式;Accept-Language 是指浏览器支持的语言;Connection 是指保持连接的方式。

    正确使用请求头的方法是在请求时加入 headers 参数,例如:

    import requests
    
    url = 'https://www.example.com'
    
    headers = {
        # Your headers go here
    }
    
    response = requests.get(url, headers=headers)
    

    如果加上请求头后出现错误,可能是因为请求头的某些信息不正确或者被网站屏蔽了。可以尝试更换 User-Agent 或者 Referer 来解决。

    在使用 requests 库时,如果想要使用 def catchData() 函数对返回的内容进行处理,则只需要将 response.content 作为参数传递给该函数即可,例如:

    def catchData(content):
        # Your code goes here
        pass
    
    response = requests.get(url, headers=headers)
    catchData(response.content)
    

    注意,如果请求头的信息不正确,可能会获取到不完整的数据或者无法获取到数据,从而影响对数据的处理。

    总之,正确使用请求头对 Python 爬虫非常重要,可以提高数据获取的可靠性和稳定性。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

关请求头啥事,就这么个写了这么多代码,确实服了!