HDU刷题神器,早已被前辈们做出来了,不过没有见过用python写的。大一的时候见识了学长写这个,当时还是一脸懵逼,只知道这玩意儿好屌…。时隔一年,决定自己实现这个功能。
(右键,在新标签页中打开查看高清图片)
(右键,在新标签页中打开查看高清图片)
所以,我们决定扒CSDN博客的代码。
搜索引擎的选择,CSDN(部分搜索结果是百度提供的)
加密了,增大了我们的工作量,所以,就直接用CSDN的(也有百度的结果)
在CSDN搜索结果的最下方,我们可以看到上图中有14W结果(好唬人啊),其实事情是这样的:
这是一个搜索hdu 1000的url,我们注意到用的get()方法传数据,发现只有p=试一下就知道,这个是页码。如果页码改为200呢/p>
开玩笑啊,14W结果呢后我们得出结论:搜索结果只有76页,而且越往后,得到我们想要代码的可能性就越小,所以我只爬到20页就结束程序
关于线程池的部分,在大牛博客说的很清楚,通过threadpool模块的源码,可以理解的很清楚
注意线程池添加任务,给任务传递多参数,需要查看源码,理解参数传递的过程,
1 #coding :utf-8
2 #@Time : 2017/8/7 11:24
3 #@Author : Yong-life
4 #@File : crawling_hdu.py
5
6 importrequests7 importre8 from headers_cookies import *
9 importthreadpool10 from searching_code importsubmit_code_from_url11
12 ”’
13 我要AK HDU14
15 需要安装threadpool,requests,pywin32模块16 先打开chrome浏览器登录hdu(cookies是从chrome拿的,刚登陆后可能因为cookie的问题程序抛出ValueError的异常,多启动几次就好了)17 ”’
18
19
20 defsearch_pid():21 problem_list =[]22 ”’共52页题目”’
23 page_number = 52 + 1
24 for i inrange(page_number):25 ”’请求url”’
26 url = ‘http://acm.hdu.edu.cn/listproblem.phpol=’ +str(i)27 response = requests.get(url, headers=get_headers(), cookies=get_cookie_from_chrome())28 ”’抓取题目信息”’
29 patternPidList = r’>’
30 problems = re.search(patternPidList, response.text).group(1).split(‘;’)31 for problem inproblems:32 try:33 pid = int(problem[4:8])34 status = int(problem[9])35 problem_list.append((pid, status))36 exceptValueError:37 ”’ValueError”’
38 print(type(pid), pid, type(status), status)39
40 returnproblem_list41
42
43 defstart_crawling():44 pid_list =[]45 ”’最大并发数量,超过10就很影响别人,相当于同时有5个人在提交代码,提交一次判断完成后才会继续提交其他代码”’
46 THREAD_NUMBER = 5
47 ”’从搜索到的第crawl_level_begin页继续开始扒代码”’
48 crawl_level_begin = 1
49 ”’分段式扒代码”’
50 crawl_level = 4
51 END_MARK =True52 whileEND_MARK:53 print(“正在爬取题目信息……”)54 for problem insearch_pid():55 pid, status =problem56 if status != 5:57 ”’多参数构造”’
58 pid_list.append(([pid, crawl_level_begin, crawl_level], None)) #必须封装为元组,否则会给参数再封装一层列表,也可以改目标函数
59 if len(pid_list) ==THREAD_NUMBER:60 ”’定义线程池大小”’
61 task_pool =threadpool.ThreadPool(THREAD_NUMBER)62 ”’任务列表”’
63 request_task =[]64 ”’构造任务列表”’
65 request_task =threadpool.makeRequests(submit_code_from_url, pid_list)66 ”’将每个任务放到线程池中,等待线程池中线程各自读取任务”’
67 [task_pool.putRequest(req) for req inrequest_task]68 ”’等待所有任务处理完成,则返回,如果没有处理完,则一直阻塞”’
69 task_pool.wait()70
71 pid_list =[]72 ”’判断是否全对,全对结束”’
73 END_MARK =False74 print(‘正在搜索AC情况,,,’)75 for status in search_pid()[1]:76 if status != 5:77 END_MARK =True78 print(‘未AK…’)79 ”’增加搜索范围”’
80 crawl_level_begin =crawl_level81 crawl_level += 4
82 print(‘增大搜索范围继续搜索…’)83 print(‘当前搜索范围:’, crawl_level_begin, crawl_level)84 break
85
86 ”’CSDN搜索最搜索到30页数据,而且部分是百度提供的结果”’
87 if crawl_level > 30:88 break
89
90 print(‘AK!’)91
92
93 if __name__ == ‘__main__’:94 start_crawling()
2)线程开始跑了:分布式思想,分块,分层,完成AK任务
爬取crawl_level_begin-crawl_level页搜索结果的url
按照url_list爬取代码
提交代码
每轮爬完6000+题后,判断是否AK,AK则结束程序,否则增加crawl_level继续查找代码提交
经过剪枝优化,代码更快了
1 #coding :utf-8
2 #@Time : 2017/8/7 15:06
3 #@Author : Yong-life
4 #@File : searching_code.py
5
6 from urllib importrequest7 importurllib8 from headers_cookies importget_headers9 importre10 importsqlite311 from sqlite_hdu importSql12 from submit_codes import *
13 importthreading14 from submit_codes importSubmitCode15 importsys16
17
18 defsubmit_code_from_url(pid, crawl_level_begin, crawl_level):19 ”’爬取url_list,提交代码”’
20 url_list =code_url_list(str(pid), crawl_level_begin, crawl_level)21 for url inurl_list:22 ”’仅爬取博客链接”’
23 if url[7:11] != ‘blog’: #删选url
24 continue
25 code =crawling_code(pid, url)26 if code == ”:27 ”’未查找到代码”’
28 continue
29 submit =SubmitCode(pid, code)30 ifsubmit.submit_manager():31 ”’AC,保存代码”’
32 sql_save_code =Sql()33 if sql_save_code.query_pid(pid) isNone:34 sql_save_code.insert_msg(pid, 5, code)35 else:36 sql_save_code.update_problem_code(pid, code)37 sql_save_code.sql_close()38 return
39
40 print(“爬取代码完毕,任务结束:” + str(pid) + “提交尚未成功!”)41 return
42
43
44 def code_url_list(problem_msg, crawl_level_begin, crawl_level): #题 和其他信息
45 ”’爬取题目链接”’
46 url_list =[]47 ”’页码,根据爬虫等级,扩大搜索范围”’
48 page_number =crawl_level_begin49 ”’最大页码”’
50 MAX_PAGE =crawl_level51 while page_number
&q
<<>”&&+’
&pid&user&lang&status
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!