最近在某著名985学子的压力下看了看了他们的python大作业,发现完全不会(,又是日常被薄纱的一天(,然后就有了这篇总结,记录一下这几天的历程。爬虫其实是属于我一直想学,一直没学的东西,正好趁这次机会迈出第一步。

request库+请求分析

这是我尝试的第一种方式,但是失败了。思路是通过fiddler工具对浏览器进行抓包,通过模拟正常用户的行为来分析请求,再用request库来进行发送请求。大作业的内容是爬取知网上的文献,内容包括题名,作者。首先我们先抓包,这是刚进入网页的请求:

抓包1 - 副本.png

这里说明网页发送get请求得到初始界面,这个过程我在postman里模拟发送请求也实现了,但是问题是出现在后面的请求中。接下来就是检索关键词之后发送的post请求,拿到一个具有多个文献名称,作者等信息的检索页面,请求头和请求体如下:

抓包2 - 副本.png

抓包3 - 副本.png

这里我用postman构造请求头和请求体发送请求,但是得到的却是下面这种情况,不知道是什么原因,后来我也是放弃了这种方式。当然有知道原因的或者是知道这种方法怎么做的请cue我一下(

发请求 - 副本.png

用selenium模拟浏览器操作

selenium是一个自动化测试的工具,可以模拟浏览器的行为,这样就模拟用户搜索信息的全过程,再把内容写入excel表就行

首先配置好浏览器环境和条件:

desired_capabilities = DesiredCapabilities.CHROME
desired_capabilities["pageLoadStrategy"] = "none"

# 设置谷歌驱动器的环境
options = webdriver.ChromeOptions()
# 设置chrome不加载图片,提高速度
options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
# 取消自动补全,不过我好像没看出来有什么用(
options.add_argument("--disable-autocomplete")
# # 设置不显示窗口
options.add_argument('--headless')
# 创建一个谷歌驱动器
driver = webdriver.Chrome(options=options)
# 设置搜索来源
source = "经济"
# 设置所需篇数
papers_need = 100
#将窗口最大化,不然好像有点问题
driver.maximize_window()
# 设置网址
url="https://kns.cnki.net/kns/advsearch?dbcode=SCDB"
# 连接上网址
driver.get(url)
time.sleep(1)
# 至此就成功打开了浏览器
print('已成功打开浏览器,url为:',url)

随后就是根据不同的网页来找搜索框,输入内容,搜索

# 输入内容到文献来源框
WebDriverWait(driver, 100).until(
EC.presence_of_element_located((By.XPATH, '''//*[@id="magazine_value1"]'''))).send_keys(source)
time.sleep(1)
print("成功输入来源:",source)

# 检索
WebDriverWait(driver, 100).until(
EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[3]/div[3]/div[2]/div[1]/div[9]"))).click()
time.sleep(1)

# 获得网页内容
def get_item(num,col=1):
index = 1
while True:
index%=20
title_XPATH = '//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[2]/a'#题名
author_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[3]'#作者
source_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[4]'#来源
time_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[5]'#发布时间
database_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[6]'#数据库
refer_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[7]'#被引
download_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[8]'#下载

这样模拟就成功了,但是这里还有个问题,就是来源搜索框中有自动补全,在主题中输入内容之后自动补全触发,这个时候就定为不到网页的内容了,而来源输入又没有这个问题。因此这个脚本只能往来源中输入内容,不能往主题中输入内容,如果知道怎么解决的请cue我一下(

最后附上整个脚本:

import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from urllib.parse import urljoin
import xlwt


desired_capabilities = DesiredCapabilities.CHROME
desired_capabilities["pageLoadStrategy"] = "none"

# 设置谷歌驱动器的环境
options = webdriver.ChromeOptions()
# 设置chrome不加载图片,提高速度
options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
options.add_argument("--disable-autocomplete")
# # 设置不显示窗口
#options.add_argument('--headless')
# 创建一个谷歌驱动器
driver = webdriver.Chrome(options=options)
# 设置搜索来源和主题
source = "经济"
theme = "导购"
# 设置所需篇数
papers_need = 100
driver.maximize_window()
# 设置网址
url="https://kns.cnki.net/kns/advsearch?dbcode=SCDB"
# 连接上网址
driver.get(url)
time.sleep(1)
print('已成功打开浏览器,url为:',url)

# 打开一个excel实例
workbook=xlwt.Workbook()
sheet=workbook.add_sheet('Sheet1')
sheet.write(0,0,'题名')
sheet.write(0,1,'作者')
sheet.write(0,2,'来源')
sheet.write(0,3,'发表时间')
sheet.write(0,4,'数据库')
sheet.write(0,5,'被引')
sheet.write(0,6,'下载')
sheet.write(0,7,'链接')


# 输入内容到文献来源框
WebDriverWait(driver, 100).until(
EC.presence_of_element_located((By.XPATH, '''//*[@id="magazine_value1"]'''))).send_keys(source)
time.sleep(1)
print("成功输入来源:",source)


# 检索
WebDriverWait(driver, 100).until(
EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[3]/div[3]/div[2]/div[1]/div[9]"))).click()
time.sleep(1)



print("成功确认检索,得到内容.....")
#获得网页内容
def get_item(num,col=1):
index = 1
while True:
index%=20
title_XPATH = '//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[2]/a'#题名
author_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[3]'#作者
source_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[4]'#来源
time_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[5]'#发布时间
database_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[6]'#数据库
refer_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[7]'#被引
download_XPATH='//*[@id="gridTable"]/div/div[2]/table/tbody/tr[' + str(index) + ']/td[8]'#下载

try:
title = driver.find_element(By.XPATH, title_XPATH).text
author=driver.find_element(By.XPATH,author_XPATH).text
source = driver.find_element(By.XPATH, source_XPATH).text
times = driver.find_element(By.XPATH, time_XPATH).text
database = driver.find_element(By.XPATH, database_XPATH).text
refer = driver.find_element(By.XPATH, refer_XPATH).text
download = driver.find_element(By.XPATH, download_XPATH).text
link=driver.find_element(By.XPATH, title_XPATH).get_attribute('href')

print(title,"\t",author,source,times,database,refer,download)
if col<num:#写入到excel中
sheet.write(col, 0, title)
sheet.write(col, 1, author)
sheet.write(col, 2, source)
sheet.write(col, 3, times)
sheet.write(col, 4, database)
sheet.write(col, 5, refer)
sheet.write(col, 6, download)
sheet.write(col, 7, link)
else:
print("-----------------------------------------------------------------------------")
print("所有爬取已经结束")
return
index += 1
col+=1
except:
print("当前页爬取结束")
index+=1
# 进入下一页
WebDriverWait(driver, 100).until(
EC.presence_of_element_located((By.XPATH, '''//*[@id="PageNext"]'''))).click()
time.sleep(1)

print("正在爬取内容.....")
print("------------------------------------------------------------------------------")
get_item(papers_need)

workbook.save('output.xls')
print("爬取结果已储存在文件output.xls中")

driver.close()