先把代码的坑说一下哈哈,尽管代码做了很多异常处理相对健壮,仍然有一个问题就是每次抓取八十条左右的数据时就会弹出验证码,代码经过微调从原来的一次性抓取十几条到八十多条,差不多半小时G一次。如果介意的话慎重订阅哈,也可私信联系我
一、需求
利用ISBN/书名抓取“全国图书馆参考咨询联盟”网站从而得到图书学科、中图分类号、主题等信息。
二、技术
selenium模拟登录,需要在代码里修改成你自己的账号密码,并且模拟滑块滑动登录。
三、技术难点
①处理了很多异常种类(查不到图书、没有学科信息,学科信息不足四级,讲到关于验证码的处理方法,虽然并没有直接处理验证码,但也描述了避免验证码弹出的一种方式,并做了相关验证,可按照文档自行修改寻求一个较为好的解决方式),文档里面图文并茂,有问题可私我要微信或直接提出问题
四、巧妙设计
①代码被反爬了之后,原来已经检索完成的内容是已经存好的,再次运行代码不会影响已经存好的信息,只从没有检索过的ISBN开始检索
②当爬取一定数量的图书信息时,就会有验证码,经过实验发现与每次模拟点击后time.sleep(??)的时间有很大关系。
ps:尝试过模拟输入验证码,首先这个验证码有很多不清晰,甚至人眼都很难区分,其次这个验证码的链接是动态变化的,复制其链接回车一次图片就改变一次,除非右键点击保存,利用图像处理返回一个字符串,填入验证码输入框,感觉挺麻烦。后来还是用time.sleep(??)调节了一下。
大概是
随机3-5s:一次能爬取17条
随机4-7s:一次能爬取25条
随机4-10s:一次能爬取86条
五、代码及详细介绍我直接放word文档里了,复制链接即可查看编辑
【金山文档】 爬取全国图书馆参考咨询联盟信息
https://kdocs.cn/l/cvYt2Bg9X0r1文章来源:https://www.toymoban.com/news/detail-454136.html
代码:文章来源地址https://www.toymoban.com/news/detail-454136.html
import random
import xlrd
import pandas as pd
from selenium import webdriver
import time
from selenium.webdriver import Chrome
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-automation'])
browser=Chrome(options=options)
url = "http://www.ucdrs.superlib.net/login/login.action"
browser.get(url)
def login():
#输入用户名
input_user = browser.find_element_by_id("userName") #查找输入框
input_user.send_keys("XXXXXX") #模拟输入用户名,宝子答应我改成你自己的账号
time.sleep(2)
#输入密码
input_pwd = browser.find_element_by_id("passWord") #查找密码框
input_pwd.send_keys("XXXXXXX") #模拟输入密码,宝子答应我改成你自己的密码
time.sleep(2)
#模拟点击登录
browser.find_element_by_xpath('//*[@id="loginFrom"]/div/div[3]/input').click()
time.sleep(8) #等待八秒,手动滑动滑块,宝子答应我八秒之内滑完
def get_fenlei():#取到分类号以及主题词
#点击图书链接
browser.find_element_by_xpath('//[@id="noscroll"]/table/tbody/tr/td[2]/form/table/tbody/tr/td[3]/table/tbody/tr/td/a').click()
time.sleep(3)
#新的页面需要调用如下代码切换window
browser.switch_to.window(browser.window_handles[1])
fenleihao = ''
zhuti = ''
#遍历表单信息,提取中图法分类号及主题词
for j in browser.find_elements_by_xpath('//*[@id="wrap2"]/div/div[5]/div[4]/div[1]/dl/dd'):
if '【中图法分类号】' in j.text:
fenleihao = j.text
print(fenleihao)
elif '【主题词】' in j.text:
zhuti = j.text
print(zhuti)
#关闭当前窗口
browser.close()
#视角切换到原始窗口
browser.switch_to.window(browser.window_handles[0])
return zhuti,fenleihao
def get_xueke(lst):
print(len(lst))
for i in range(len(lst)):
print(i)
#Sub用来存储学科信息,zhuti用来存储主题,fenleihao用来存储中图分类号
Sub, zhuti, fenleihao='','',''
#看一下表格中这条图书有没有查询过,未查询的时候对应”xueke“字段是空的状态
if pd.isnull(df.iat[i,1]):
print(lst[i],'成功')
search_text = browser.find_element_by_xpath('//*[@id="sw"]') #查找检索框
search_text.send_keys(lst[i]) #模拟输入ISBN
#点击”中文搜索“
browser.find_element_by_xpath('//*[@id="f2"]/div[2]/input[1]').click()
time.sleep(random.randint(4,10))
if '0 种,用时' in browser.find_element_by_xpath('//*[@id="searchinfo"]/b').text:#查不到此图书
print(lst[i], '异常')
browser.back() #回退网页一次
Sub = '无此图书'
browser.find_element_by_xpath('//*[@id="sw"]').clear() #清空检索框
time.sleep(random.randint(4, 10))
else:
try:#正常情况下图书有学科信息向下点击
yiji = browser.find_element_by_xpath('//*[@id="leftcata"]/div[3]/div[2]/a')
Sub+=yiji.text
yiji.click()
time.sleep(random.randint(4, 10))
try:#正常情况下图书有二级学科向下点击
erji = browser.find_element_by_xpath('//*[@id="leftcata"]/div[3]/div[2]/a')
Sub+=erji.text
erji.click()
time.sleep(random.randint(4, 10))
try:#正常情况下图书有三级学科向下点击
sanji = browser.find_element_by_xpath('//*[@id="leftcata"]/div[3]/div[2]/a')
Sub+=sanji.text
sanji.click()
time.sleep(random.randint(4, 10))
try:#正常情况下图书有四级学科向下点击,并回退五次返回检索首页
siji = browser.find_element_by_xpath('//*[@id="leftcata"]/div[3]/div[2]/a')
Sub+=siji.text
siji.click()
time.sleep(random.randint(4, 10))
zhuti, fenleihao = get_fenlei()
browser.back()
browser.back()
browser.back()
browser.back()
browser.back()
browser.find_element_by_xpath('//*[@id="sw"]').clear()
except:#此异常是为了处理只有三级学科的情况
zhuti, fenleihao = get_fenlei() #点击图书链接,获取相应信息,关闭当前窗口
browser.back() #回退四次
browser.back()
browser.back()
browser.back()
browser.find_element_by_xpath('//*[@id="sw"]').clear() #清空检索框
except:#此异常是为了处理只有二级学科的情况
zhuti, fenleihao = get_fenlei() #点击图书链接,获取相应信息,关闭当前窗口
browser.back() #回退三次
browser.back()
browser.back()
browser.find_element_by_xpath('//*[@id="sw"]').clear() #清空检索框
except:#此异常是为了处理只有一级学科的情况
zhuti, fenleihao = get_fenlei() #点击图书链接,获取相应信息,关闭当前窗口
browser.back() #回退两次
browser.back()
browser.find_element_by_xpath('//*[@id="sw"]').clear() #清空检索框
except:#此异常是为了处理没有学科的情况
Sub='无学科分类信息'
zhuti, fenleihao = get_fenlei() #点击图书链接,获取相应信息,关闭当前窗口
browser.back() #回退一次
browser.find_element_by_xpath('//*[@id="sw"]').clear() #清空检索框
#每检索一本图书就存入表格一次
df.loc[i, 'xueke'] = str(Sub)
df.loc[i, 'fenleihao'] = fenleihao
df.loc[i, 'zhutici'] = zhuti
df.to_excel('book.xlsx',index=False)
#”xueke"不为空值表示是查询过的图书,则开始下一本图书检索
else:
continue
if __name__ == '__main__':
# 利用openpyxl读取表格,在你相应的环境里要安装openpyxl:pip install openpyxl
df = pd.read_excel('book.xlsx', header=0, engine='openpyxl')
Isbn_set = list(df['ISBN']) # 读取表格的ISBN这一列存为列表
login() # 登录需要手动滑动
get_xueke(Isbn_set)
到了这里,关于利用ISBN/书名爬取“全国图书馆参考咨询联盟”网站从而得到图书学科、中图分类号、主题等信息的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!