当前位置:   article > 正文

python简易网络爬虫(以研招网招生信息为例)_爬虫考研

爬虫考研

写在前面

一是必要工作,二是代码解析,三是直接上手使用(无需基础),如果只是当作工具可只看一三部分

一.准备工作

1.安装python和pycharm(这里不多解释,放上别人的链接)

Python安装教程(新手)_python tcl/tk support-CSDN博客

2.更新pip:

python -m pip install --upgrade pip

3.安装对应模块:打开anaconda prompt(或者在pycharm终端(Terminal)中)依次输入:

  1. pip install requests
  2. pip install beautifulsoup4
  3. pip install pandas
  4. pip install lxml
  5. # beautifulsoup4后面加个4,对应当前版本,不加可能会pip失败

4.创建python文件,导入对应模块 

  1. import requests
  2. from bs4 import BeautifulSoup
  3. from pandas.core.frame import DataFrame
  4. import re

requests:网络请求模块

re:正则表达式

pandas:基于Numpy的处理文本或者表格数据的工具

beautifulsoup:用于从HTML和XML文件中提取数据

二.开搞

  1. 函数部分:定义一个名为 Graduate 的类,用于封装爬取数据的相关方法:

    • __init__(self, province, category, provinceName):初始化方法,设置请求头和空的数据列表,并接受省份代码、专业代码和省份名称作为参数。

      1. def __init__(self, province, category, provinceName):
      2. self.head = {
      3. "User-Agent":
      4. "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKi"
      5. "t/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
      6. } ##创建字典head,key是 "User-Agent",value是一个标识浏览器的用户代理字符串,用于模拟浏览器发送请求
      7. self.data = [] #创建空列表用于存储爬取的数据
      8. self.province = province #存储省份代码
      9. self.category = category #存储专业代码
      10. self.provinceName = provinceName #存储省份名称
    • get_list_fun(self, url, name):获取提交表单代码的方法,发送 GET 请求并将响应的 JSON 数据写入文件。

      1. def get_list_fun(self, url, name):
      2. """获取提交表单代码"""
      3. response = requests.get(url, headers=self.head) #get方法发送爬取请求
      4. resprovince = response.json() #从响应对象中获取 JSON 格式的数据,并将其转换为 Python 对象
      5. with open(name + ".txt", "w") as f: #打开文件 name + ".txt",以写入模式打开("w"),并使用 with 上下文管理器,确保文件在退出上下文时被正确关闭。文件对象存储在变量 f 中。
      6. for x in resprovince: #遍历解析出的 JSON 数据
      7. f.write(str(x))
      8. f.write("\n")

    • get_list(self):获取省份、学科门类和专业编号数据,并写入对应的文本文件。

      1. def get_list(self):
      2. """
      3. 分别获取省,学科门类,专业编号数据
      4. 写入txt文件
      5. """
      6. self.get_list_fun("http://yz.chsi.com.cn/zsml/pages/getSs.jsp",
      7. "province") #传递省份数据的 URL 和文件名 "province"
      8. self.get_list_fun('http://yz.chsi.com.cn/zsml/pages/getMl.jsp',
      9. "category") #传递学科门类数据的 URL 和文件名 "category"
      10. self.get_list_fun('http://yz.chsi.com.cn/zsml/pages/getZy.jsp',
      11. 'major') #传递专业编号数据的 URL 和文件名 "major"

    • get_school_url(self):发送 POST 请求获取学校网址列表,并通过正则表达式提取出学校的网址。

      1. def get_school_url(self):
      2. """
      3. 输入省份,
      4. 发送post请求,获取数据
      5. 提取数据
      6. 必填省份,学科门类,专业可选填
      7. 返回学校网址
      8. """
      9. url = "https://yz.chsi.com.cn/zsml/queryAction.do"
      10. data = {
      11. "ssdm": self.province,
      12. "yjxkdm": self.category,
      13. }
      14. response = requests.post(url, data=data, headers=self.head)
      15. html = response.text
      16. reg = re.compile(r'(<tr>.*? </tr>)', re.S) #使用 re.S 标志,表示点 (.) 可以匹配换行符
      17. content = re.findall(reg, html)
      18. schools_url = re.findall('<a href="(.*?)" target="_blank">.*?</a>',
      19. str(content))
      20. #从匹配的字符串中提取所有学校网址,即 <a> 标签中 href 属性的值,并将这些网址存储在列表 schools_url 中
      21. return schools_url

    • get_college_data(self, url):获取一个学校所有学院的数据,发送 GET 请求获取页面内容,并通过正则表达式提取出学院的网址,方法与4类似。

      1. def get_college_data(self, url):
      2. """返回一个学校所有学院数据"""
      3. response = requests.get(url, headers=self.head)
      4. html = response.text
      5. colleges_url = re.findall(
      6. '<td class="ch-table-center"><a href="(.*?)" target="_blank">查看</a>',
      7. html)
      8. return colleges_url

    • get_final_data(self, url):获取一个学校一个学院一个专业的数据,发送 GET 请求获取页面内容,并使用 BeautifulSoup 解析页面,提取出包含招生信息的表格数据。

      1. def get_final_data(self, url):
      2. """输出一个学校一个学院一个专业的数据"""
      3. temp = []
      4. response = requests.get(url, headers=self.head)
      5. html = response.text
      6. soup = BeautifulSoup(html, features='lxml') #使用 BeautifulSoup 解析 HTML 内容,生成 BeautifulSoup 对象 soup,此处使用的是 'lxml' 解析器
      7. summary = soup.find_all('td', {"class": "zsml-summary"})
      8. for x in summary:
      9. temp.append(x.get_text())
      10. self.data.append(temp) ##将包含当前学校、学院、专业等相关信息的临时列表 temp 利用append方法添加到类 self.data 中

    • get_schools_data(self):获取所有学校的数据,遍历学校网址列表,依次获取每个学校的招生信息。

      1. def get_schools_data(self):
      2. """获取所有学校的数据"""
      3. url = "http://yz.chsi.com.cn"
      4. schools_url = self.get_school_url()
      5. amount = len(schools_url) #计算学校网址列表的长度,即学校的数量,并将其存储在变量 amount 中
      6. i = 0
      7. for school_url in schools_url:
      8. i += 1
      9. url_ = url + school_url #构造当前学校的完整 URL
      10. # 找到一个学校对应所有满足学院网址
      11. colleges_url = self.get_college_data(url_)
      12. print("已完成" + self.provinceName + "第" + str(i) + "/" +
      13. str(amount) + "个高校爬取")
      14. #time.sleep(1)
      15. for college_url in colleges_url:
      16. _url = url + college_url
      17. self.get_final_data(_url)

    • get_data_frame(self):将列表形式的数据转换为 DataFrame,并保存为 CSV 文件。

      1. def get_data_frame(self):
      2. """将列表形数据转化为数据框格式"""
      3. data = DataFrame(self.data)
      4. data.to_csv(self.provinceName + "查询招生信息.csv", encoding="utf_8_sig")
      5. #.to_csv() 方法用于将数据写入 CSV 文件,其中的参数 encoding="utf_8_sig" 指定了 CSV 文件的编码为 UTF-8,以确保能够正确地处理中文字符

  2. main部分:定义要抓取的省份代码列表 provinceList 和省份代码与名称的对应字典 provinceNmaeDict。然后,遍历省份代码列表,为每个省份创建一个 Graduate 实例,调用 get_schools_data 方法获取数据,并调用 get_data_frame 方法将数据保存为 CSV 文件。

    1. if __name__ == '__main__':
    2. provinceList = [
    3. '11'
    4. ] # 要抓取的省份代码
    5. provinceNmaeDict = {
    6. '11': '北京市'
    7. } #省份代码和对应的省份名称
    8. category = "0839" #指定要抓取的专业代码
    9. for i in provinceList:
    10. province = i
    11. if province in provinceNmaeDict.keys():
    12. spyder = Graduate(province, category, provinceNmaeDict[province])
    13. spyder.get_schools_data()
    14. spyder.get_data_frame() #调用get_data_frame 方法,将获取到的数据转换为数据框格式,并保存为 CSV 文件

运行该程序,

同级目录下生成了一个csv文件,我们可以找到该文件的本地地址,用wps或者excel打开

效果如图,爬取成功

三.写在最后

直接使用,需要修改以下两点:

1.将main部分的provincelist和provinceNmaeDict的省份代码只保留自己想查询的,如北京(11)

2. category的专业代码换成自己想要查询的,打开研招网硕士专业目录可以看到对应编号,如电子科学与技术(080900)

完整代码如下:

  1. import requests
  2. from bs4 import BeautifulSoup
  3. from pandas.core.frame import DataFrame
  4. import re
  5. class Graduate:
  6. def __init__(self, province, category, provinceName):
  7. self.head = {
  8. "User-Agent":
  9. "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKi"
  10. "t/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
  11. }
  12. self.data = []
  13. self.province = province
  14. self.category = category
  15. self.provinceName = provinceName
  16. def get_list_fun(self, url, name):
  17. """获取提交表单代码"""
  18. response = requests.get(url, headers=self.head)
  19. resprovince = response.json()
  20. with open(name + ".txt", "w") as f:
  21. for x in resprovince:
  22. f.write(str(x))
  23. f.write("\n")
  24. def get_list(self):
  25. """
  26. 分别获取省,学科门类,专业编号数据
  27. 写入txt文件
  28. """
  29. self.get_list_fun("http://yz.chsi.com.cn/zsml/pages/getSs.jsp",
  30. "province")
  31. self.get_list_fun('http://yz.chsi.com.cn/zsml/pages/getMl.jsp',
  32. "category")
  33. self.get_list_fun('http://yz.chsi.com.cn/zsml/pages/getZy.jsp',
  34. 'major')
  35. def get_school_url(self):
  36. """
  37. 输入省份,
  38. 发送post请求,获取数据
  39. 提取数据
  40. 必填省份,学科门类,专业可选填
  41. 返回学校网址
  42. """
  43. url = "https://yz.chsi.com.cn/zsml/queryAction.do"
  44. data = {
  45. "ssdm": self.province,
  46. "yjxkdm": self.category,
  47. }
  48. response = requests.post(url, data=data, headers=self.head)
  49. html = response.text
  50. reg = re.compile(r'(<tr>.*? </tr>)', re.S)
  51. content = re.findall(reg, html)
  52. schools_url = re.findall('<a href="(.*?)" target="_blank">.*?</a>',
  53. str(content))
  54. return schools_url
  55. def get_college_data(self, url):
  56. """返回一个学校所有学院数据"""
  57. response = requests.get(url, headers=self.head)
  58. html = response.text
  59. colleges_url = re.findall(
  60. '<td class="ch-table-center"><a href="(.*?)" target="_blank">查看</a>',
  61. html)
  62. return colleges_url
  63. def get_final_data(self, url):
  64. """输出一个学校一个学院一个专业的数据"""
  65. temp = []
  66. response = requests.get(url, headers=self.head)
  67. html = response.text
  68. soup = BeautifulSoup(html, features='lxml')
  69. summary = soup.find_all('td', {"class": "zsml-summary"})
  70. for x in summary:
  71. temp.append(x.get_text())
  72. self.data.append(temp)
  73. def get_schools_data(self):
  74. """获取所有学校的数据"""
  75. url = "http://yz.chsi.com.cn"
  76. schools_url = self.get_school_url()
  77. amount = len(schools_url)
  78. i = 0
  79. for school_url in schools_url:
  80. i += 1
  81. url_ = url + school_url
  82. # 找到一个学校对应所有满足学院网址
  83. colleges_url = self.get_college_data(url_)
  84. print("已完成" + self.provinceName + "第" + str(i) + "/" +
  85. str(amount) + "个高校爬取")
  86. #time.sleep(1)
  87. for college_url in colleges_url:
  88. _url = url + college_url
  89. self.get_final_data(_url)
  90. def get_data_frame(self):
  91. """将列表形数据转化为数据框格式"""
  92. data = DataFrame(self.data)
  93. data.to_csv(self.provinceName + "查询招生信息.csv", encoding="utf_8_sig")
  94. if __name__ == '__main__':
  95. provinceList = [
  96. '11', '12', '13', '14', '15', '21', '22', '23', '31', '32', '33', '35',
  97. '36', '41', '42', '43', '44', '51', '52', '53', '61', '62'
  98. ] # 要抓取的省份代码
  99. provinceNmaeDict = {
  100. '11': '北京市',
  101. '12': '天津市',
  102. '13': '河北省',
  103. '14': '山西省',
  104. '15': '内蒙古自治区',
  105. '21': '辽宁省',
  106. '22': '吉林省',
  107. '23': '黑龙江省',
  108. '31': '上海市',
  109. '32': '江苏省',
  110. '33': '浙江省',
  111. '34': '安徽省',
  112. '35': '福建省',
  113. '36': '江西省',
  114. '37': '山东省',
  115. '41': '河南省',
  116. '42': '湖北省',
  117. '43': '湖南省',
  118. '44': '广东省',
  119. '45': '广西壮族自治区',
  120. '46': '海南省',
  121. '50': '重庆市',
  122. '51': '四川省',
  123. '52': '贵州省',
  124. '53': '云南省',
  125. '54': '西藏自治区',
  126. '61': '陕西省',
  127. '62': '甘肃省',
  128. '63': '青海省',
  129. '64': '宁夏回族自治区',
  130. '65': '新疆维吾尔自治区',
  131. '71': '台湾省',
  132. '81': '香港特别行政区',
  133. '82': '澳门特别行政区'
  134. } #省份代码和对应的省份名称
  135. category = "083903" #专业代码
  136. for i in provinceList:
  137. province = i
  138. if province in provinceNmaeDict.keys():
  139. spyder = Graduate(province, category, provinceNmaeDict[province])
  140. spyder.get_schools_data()
  141. spyder.get_data_frame()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/1001644
推荐阅读
相关标签
  

闽ICP备14008679号