爬虫时为啥加上请求头之后会出现错误,不加请求头可以吗,加上请求头为啥会影响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是因为你调用了上面方法的输出结果作为入参
不知道你这个问题是否已经解决, 如果还没有解决的话:答案:
为了模拟正常浏览器对网页的访问,使用请求头来进行 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 爬虫非常重要,可以提高数据获取的可靠性和稳定性。
关请求头啥事,就这么个写了这么多代码,确实服了!