Python3爬虫--两种方法(requests(urllib)和BeautifulSoup)爬取网站pdf

  • 1、任务简介

本次任务是爬取IJCAI(国际人工智能联合会议)最新2018年的pdf论文文件。

本次编码用到了正则表达式从html里面提取信息,如下对正则表达式匹配规则作简要的介绍。

  • 2、正则表达式规则

\w匹配字母数字及下划线

\W匹配非字母数字及下划线

\s匹配任意空白字符,等价于 [\t\n\r\f].

\S匹配任意非空字符

\d匹配任意数字,等价于 [0-9]

\D匹配任意非数字

\A匹配字符串开始

\Z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串

\z匹配字符串结束

\G匹配最后匹配完成的位置

\n匹配一个换行符

\t匹配一个制表符

^匹配字符串的开头

$匹配字符串的末尾

.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。

[...]用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'

[^...]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。

*匹配0个或多个的表达式。

+匹配1个或多个的表达式。

?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式

{n}精确匹配n个前面表达式。

{n, m}匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式

a|b匹配a或b

( )匹配括号内的表达式,也表示一个组

  • 3、代码实现

第一种方法实现如下:

 1 # -*- coding: utf-8 -*-
 2 """
 3 Created on Tue Aug  7 12:32:25 2018
 4 
 5 @author: Lenovo
 6 """
 7 import urllib.request
 8 import re
 9 import os
10 
11 url = 'http://www.ijcai.org/proceedings/2017/'
12 
13 def getHtml(url):
14     request = urllib.request.Request(url)
15     request.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36')
16     response = urllib.request.urlopen(request)
17     html = response.read()
18     
19     return html
20 
21 html = getHtml(url)
22 
23 def getPaper(html):
24     if not os.path.exists('IJCAI_2017') : #文件夹不存在时,再进行创建
25         os.mkdir('IJCAI_2017')
26     os.chdir(os.path.join(os.getcwd(), 'IJCAI_2017'))
27     
28     reg = 'href="(\d{4}\.pdf)"'        #正则表达式
29     papre = re.compile(reg)
30     addr_list = re.findall(papre, html.decode('utf-8'))
31     
32     num = len(addr_list)
33     print('论文总数:', num)
34     
35     m =1
36     for paperurl in addr_list:
37         fname = '%s.pdf' %m#论文下载名
38         paper_url = url + paperurl#论文下载地址
39         print(paper_url)
40         paper = getHtml(paper_url)
41         
42         with open(fname, 'wb') as f:
43            f.write(paper)
44         
45         m += 1
46         
47         print('已下载')
48         f.close()
49 
50 getPaper(html)

第二种方法实现如下:

 1 # -*- coding: utf-8 -*-
 2 """
 3 Created on Sun Aug  5 10:41:13 2018
 4 
 5 @author: Lenovo
 6 """
 7 import requests
 8 import os
 9 from bs4 import BeautifulSoup, Comment
10 
11 url = 'http://www.ijcai.org/proceedings/2018/'
12 headers = {'Host' : 'www.ijcai.org', 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
13  
14 def find_paper():
15     html = requests.get(url, headers = headers).content
16     s = BeautifulSoup(html, 'lxml') 
17     
18     #要爬取的信息在页面解析后的注释内,获取注释内容,结果返回所有注释列表
19     comments = s.find_all(text=lambda text:isinstance(text, Comment))
20     
21     #论文信息为comments[2],再次使用beautifulsoup解析
22     soup = BeautifulSoup(comments[2], 'lxml')
23     
24     titles = soup.find_all("div", class_ = "title")#由于class是关键字所以加一个'_'
25     details = soup.find_all("div", class_ = "details")
26     
27     return titles, details
28 
29 titles, details = find_paper()
30 
31 def download_paper():
32     if not os.path.exists('IJCAI_2018') : #文件夹不存在时,再进行创建
33         os.mkdir('IJCAI_2018')
34     os.chdir(os.path.join(os.getcwd(), 'IJCAI_2018'))#os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略,os.getcwd()获取当前工作目录,即当前python脚本工作的目录路径,os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
35     
36     num = len(titles)
37     print('论文总数:', num)
38         
39     for i in range(num):
40         detail = details[i]
41         
42         fname = detail.contents[1].get('href')#论文下载名
43         deatil_url = url + fname#论文下载地址
44         
45         print(deatil_url)
46         r = requests.get(deatil_url)
47         
48         with open(fname, 'wb') as f:
49            f.write(r.content)
50         
51         print('已下载:', titles[i].string)
52         f.close()
53 
54 if __name__ == '__main__':
55     download_paper()

4、运行结果

2018年总共870篇结果如下:

posted @ 2018-08-07 15:42  J.mg  阅读(2711)  评论(1编辑  收藏  举报