想学爬虫很久了,还好一下午搞定了
主要是参考了这个老哥的博客:莫烦 Python,其他的用法都是上网去查查查就可以了
爬虫不仅仅局限于用 Python,其实用 perl 也行,目的就是能够自动的从网上把需要的东西下载下来,Python 的好处是可以直接使用一些集成好的库非常的方便,比如说需要从 Excel 中读取信息,这些直接用 Python 的库非常的方便。
第一个步骤是找到要下载的链接,一般来说需要自己从一个网站上爬取,这次想开始做的一个原因是 Springer 在疫情期间开放了自己的电子书下载,不下载白不下载。
薅羊毛的事情国内外都是一样的,有个老哥整理了电子书链接,里面有个 Excel,但是并不是下载链接,点进去会跳转到 Springer 的说明页面,也就是下面这样,正常点击下载按钮就行了。
获取链接就很简单了,直接从 Excel 中读取就行了,首先先把 Excel 删减成自己想要的内容,我的 Excel 变成下面的模样了,里面的前三列是需要用来命名文件的,总不希望下载下来的文件是编号吧;第四列是用来分类存文件夹的;第五列就是上面说的 Springer 的链接。
下面就开始读 Excel
首先先安装 xlrd,CentOS 的麻烦就在于权限问题,直接 sudo 了
pip3 install xlrd
然后就可以开始读 Excel 操作了
wb = xlrd.open_workbook(filename=filelist) # Read excel
sheet1 = wb.sheet_by_index(0) # Get the first sheet
row = sheet1.nrows # Get the total row numbers
row_value = sheet1.row_values(1) # Get the second row content
最好获取行数,免得读出的时候超过了;下面就开始获取需要的信息,比如说第二行就是第一个需要下载的内容
上面的 row_value[4] 可以访问到 Springer 的页面,有了这个页面就可以开始干活了。
首先先把 BeautifulSoup 安装好
pip3 install beautifulsoup4
然后就开始干活,先是找到链接,然后按照分类创建文件夹,创建文件夹的函数后面会写。
接下来就是用 urlopen 获得网页的内容,这里一定要用 try... catch 结构,因为链接不一定都是可以访问的,遇到不行的链接就跳过它。
link = row_value[4]
folder = row_value[3]
mkfolder(folder)
save_filename = folder + '/' + row_value[0]+'_'+row_value[1]+'_'+row_value[2]+'.pdf'
try:
html = urlopen(link).read().decode('utf-8')
except urllib.error.URLError as e:
print(e.reason)
print('Next file')
e_info = 'No.' + str(i) + ' Download ' + save_filename + ' from ' + link + 'failure'
print(e_info)
下面就到了 BeautifulSoup 的部分,先是把网页转换成 lxml,然后再用正则表达式找到要的内容,这部分就要看网页代码,找到下载链接的公共部分,比如说这个 pdf 的下载链接都是这样的,都有个 title,一找就找到。
<a href="/content/pdf/10.1007%2Fb100747.pdf" target="_blank" class="c-button c-button--blue c-button__icon-right test-download-book-options test-bookpdf-link" title="Download this book in PDF format" rel="noopener" data-track="click" data-track-action="Book download - pdf" data-track-label="">
...
</a>
soup = BeautifulSoup(html, features='lxml')
pdf_link = soup("a",{"title":re.compile('Download this book in PDF format')})
if(len(pdf_link) == 0):
print('Error in get link')
print('Line ')
print(i)
print(link)
link_name = pdf_link[0]
网上提供了三种下载方法,考虑到文件不大,直接用 urlretrieve
link_name = pdf_link[0]
download_link = 'https://link.springer.com'+link_name['href']
其实这个可以用来下载会议报告,很多会议都有自己的 indico,用爬虫一跑,可以全部下下来,非常舒爽。
缺啥自己装啥
import os
import xlrd
from bs4 import BeautifulSoup
from urllib.request import urlopen
import urllib
import re
def download_file(filelist='springer_list.xlsx',start=1,end=30):
link_prefix = 'http://link.springer.com'
wb = xlrd.open_workbook(filename=filelist)
sheet1 = wb.sheet_by_index(0)
row = sheet1.nrows
pattern = re.compile(r'.*\.pdf')
if(end > row):
end = row
c_info = 'Max file number: '+ str(row)+'. Change to '+str(row)
print(c_info)
for i in range(start-1,end):
row_value = sheet1.row_values(i)
link = row_value[4]
folder = row_value[3]
mkfolder(folder)
save_filename = folder + '/' + row_value[0]+'_'+row_value[1]+'_'+row_value[2]+'.pdf'
try:
html = urlopen(link).read().decode('utf-8')
except urllib.error.URLError as e:
print(e.reason)
print('Next file')
e_info = 'No.' + str(i) + ' Download ' + save_filename + ' from ' + link + 'failure'
print(e_info)
continue
soup = BeautifulSoup(html, features='lxml')
pdf_link = soup("a",{"title":re.compile('Download this book in PDF format')})
if(len(pdf_link) == 0):
print('Error in get link')
print('Line ')
print(i)
print(link)
continue
link_name = pdf_link[0]
## result = pattern.findall(link_name)
download_link = link_prefix + link_name['href']
ss_info = 'No.' + str(i) + ' Download ' + save_filename + ' from ' + download_link
print(ss_info)
urllib.request.urlretrieve(download_link,save_filename)
s_info = 'Download ' + save_filename + ' successfully'
print(s_info)
def mkfolder(folder_name):
folder = os.path.exists(folder_name)
if not folder:
os.makedirs(folder_name)
info = 'Make folder '+folder_name
print(info)
欢迎关注我的语雀主页和公众号