python爬虫抓取LeetCode题目
来源:互联网 发布:编程电脑配置要求2017 编辑:程序博客网 时间:2024/06/05 04:19
最近不知道为什么leetcode有时候会上不去,不能愉快的刷题了。
毛主席教导我们要自己动手,丰衣足食,于是,这几天学习了一下python,写了个简单的爬虫抓取leetcode上的题目。
以前没有接触过python,于是,网上找资料学习基础语法,学了一下变量,循环,选择,函数之类的语法。然后找了一些爬虫的基本知识和ptyhon爬虫的简单例子,花了一天时间写了一个简单的爬虫。
好了,废话不多说,开始进入正题。
为了处理http请求和解析html引入第三库Requests和BeautifulSoup。
这是leetcode的题目列表,可以看出题目是放在一个table里面的,再查看源码,找到那个table
<table id="problemList" class="table table-striped table-centered">
所以首先找到id为‘problemList’的table,table有thead和tbody,通过审查元素可以看出来题目信息在tbody的tr标签里
<tr> <td style="display: none;"> <span class="None"> </span> </td> <td>253</td> <td> <a href="/problems/meeting-rooms-ii/">Meeting Rooms II</a> <i class="fa fa-lock"></i> </td> <td>29.7%</td> <td value="2">Medium</td> </tr>
这里可以看出来题目信息嵌在各个td里面,所以我们可以通过BeautifulSoup的函数来获得其中信息。
a标签里面有链接,通过链接可以获得具体题目。
题目分为免费和付费,从源码可以看出来两者的差别在于有没有i标签,所以只要找到所有没有i标签的tr就行了。
点开具体题目,查看源代码。
可以看出来题目信息在一个class为question-content的div里面
只要获得这个div子元素里面的文字就能抓取到题目信息。
找到规律之后就可以开始编码了。
#coding=utf-8 '''author Jon Leedate 8/9/2015'''import requestsfrom bs4 import BeautifulSoupimport os#获得题目内容def getProblemContent(href): url = 'https://leetcode.com' + href try: req = requests.get(url,headers = headers,timeout=20) except (requests.exceptions.ReadTimeout,requests.exceptions.ConnectTimeout):#处理连接超时 print('time out') return 'time out' problemPage = BeautifulSoup(req.text) questionContents = problemPage.select('.question-content')#找到存放题目的div contents = questionContents[0].find_all(['p','pre'])#找到所有p和pre标签 contentText = '' for content in contents: contentText += content.get_text() req.close() return contentText#写入文件def saveQuestion(content): #content['title'].replace(' ','_')#将空格替换成_ name = content['id'] + '_' + content['title'] + '.txt'#文件名 id_title.txt 如 242_Valid Anagram.txt if not os.path.exists(name):#文件不存在 创建文件 print('create',name) f = open(name,'wb+')#打开文件 准备写入#这里有个问题 直接写入 content['content']会报编码错误 f.write(content['content'].encode(encoding='utf_8'))#写入文件 f.close()#关闭文件#伪装成浏览器headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36'}r = requests.get('https://leetcode.com/problemset/algorithms/',headers = headers)#print(r.status_code)#print(r.text)soup = BeautifulSoup(r.text)#print(soup.title.string)#找到题目所在位置table = soup.find(id='problemList')#题目信息存放在tbody的tr中 找出所有trtr = table.tbody.find_all('tr')#找出其中免费题目 观察源码 没有i标签的即为免费题目problemListEasy = [] #初始化列表 用于存放题目problemListMedium = [] #初始化列表 用于存放题目problemListHard = [] #初始化列表 用于存放题目for problem in tr: if type(problem.find('i')) is type(None): #记录题目 id title link acceptance difficulity 以字典方式存入列表 td = problem.find_all('td') p_id =td[1].string title = td[2].a.string link = td[2].a.get('href') acceptance = td[3].string difficulity = td[4].string #读取内容 content = getProblemContent(link) #print(content) p_dict = {'id':p_id,'title':title,'content':content,'acceptance':acceptance,'difficulity':difficulity} print(p_dict['id']) #将问题根据难度放入不同列表 if difficulity == 'Easy': problemListEasy.append(p_dict) elif difficulity == 'Medium': problemListMedium.append(p_dict) else: problemListHard.append(p_dict)#文件操作 创建存放题目的目录及文件#切换路径os.chdir('F:\ComputerRobotData')if not os.path.exists('leetcode'):#目录不存在 则创建 os.mkdir('leetcode')os.chdir('leetcode')#创建easy medium hard三个目录存放相应题目if not os.path.exists('easy'):#目录不存在 则创建 os.mkdir('easy')if not os.path.exists('medium'):#目录不存在 则创建 os.mkdir('medium')if not os.path.exists('hard'):#目录不存在 则创建 os.mkdir('hard')#写入简单题os.chdir('easy')#print(problemListEasy)for pEasy in problemListEasy: saveQuestion(pEasy)#写入中等题os.chdir('../medium')#print(problemListMedium)for pMedium in problemListMedium: saveQuestion(pMedium)#写入困难题os.chdir('../hard')#print(problemListHard)for pHard in problemListHard: saveQuestion(pHard) print('finish!!')
这样就能抓取题目并保存到本地了。
遇到问题:
在写入文件的时候直接写入content[‘content’]会报错,UnicodeEncodeError: ‘gbk’ codec can’t encode character ‘\xa9’ in position 49: illegal multibyte sequence,可是我的编码已经设置成utf-8,所以,无奈之下改用二进制数据写入,问题解决。但是上面那个错误是怎么回事,希望各位大神指导。
刚开始接触python,感觉还是挺有趣的,整个程序也就100多行。不过,虽然效果是可以实现,但是整段代码并没有优化过,基本上是函数式的编程,没有体现封装和面向对象的思想,以后还有很大的优化空间。
- python爬虫抓取LeetCode题目
- python爬虫抓取图片
- Python爬虫抓取
- python 爬虫抓取奥数题
- python爬虫抓取-helloworld
- python 爬虫 基本抓取
- python网络爬虫抓取图片
- Python爬虫抓取网页图片
- python爬虫CSDN文章抓取
- Python爬虫抓取csdn博客
- python 爬虫抓取心得分享
- 使用python爬虫抓取学术论文
- Python抓取段子的爬虫
- python 网络爬虫抓取图片
- python网络爬虫抓取图片
- Python爬虫抓取动态数据
- python网络爬虫抓取图片
- python实现爬虫抓取段子
- 支持向量机
- Java字符串切割
- HDU 1257.最少拦截系统【8月9】
- poj2492 A Bug's Life 并查集
- DP - hdu5291 Candy Distribution
- python爬虫抓取LeetCode题目
- 101. Symmetric Tree
- 装wampserver时显示计算机丢失MSVCR110.dll
- hdu 1142(最短路dijkstra)
- 【Qt OpenGL教程】21:线、反走样、正投影和简单的声音
- C++:复制构造函数___浅拷贝
- UVA - 1442 Cav
- Leetcode# 110 Balanced Binary Tree
- 黑马程序员 oc随记 写一个手动内存释放