上一次我们拿学校的URP做了个小小的demo。。。。

其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比

另外也可以写一个物理实验自动选课。。。

但是出于多种原因,,还是绕开这些敏感话题。。

今天,我们来扒一下cf的题面! PS:本代码不是我原创

1. 必要的分析

1.1 页面的获取

一般情况CF的每一个 contest 是这样的:

对应的URL是:http://codeforces.com/contest/xxx

还有一个Complete problemset页面,它是这样的:

对应的URL是:http://codeforces.com/contest/xxx/problems

可以发现,每一个contest除了xxx不一样外,其他都一样。

这样,我们就可以通过修改xxx的内容,来决定爬取哪一场比赛的题面了。

1.2 src保存问题

要保存整个网站,除了html的文本内容外,还需要将页面中对应的其他资源一起保存下来。

这里,我们分两步来做

  • 第一步,将html页面的头部以及对应的资源事先保存下来,因为这些头部都是一样的
  • 第二步,每访问一个contest,就下载其中相应的资源文件,并保存到相应的目录。

1.3 一些扩展

保存为html并不是很方便查看,我们可以使用wkhtmltopdf将html转化为pdf。

脚本如下:

if [ -d ./pdf ]; then
:
else
mkdir -p pdf
fi cd html
for h in *.html;
do
wkhtmltopdf -q "$h" "../pdf/`echo "$h"|sed "s/\.html/\.pdf/"`"
done

我们还可以写一个用于清理的脚本:

rm -f contest/*
rm -f html/*
rm -f problem/*
rm -f src/*

那么最后,我们拥有如下文件:

  • cachesheader.html是我们之间保存的一些共用文件
  • clear.shhtml2pdf.sh是我们写的脚本
  • crawl_html.py是我们的爬虫

2. 代码

#coding=utf-8

# 导入需要用到的模块
import urllib2
import re
import os
import sys
import threading
import HTMLParser # 抓取网页内容
def get_html(url):
t=5
while t>0:
try:
return urllib2.urlopen(url).read()
except:
t-=1
print "open url failed:%s"%url # 编译正则表达式
def allre(reg):
return re.compile(reg,re.DOTALL) # 下载页面资源
def down_src(html,title):
src=allre(r'src="(.*?)"').findall(html)
id = 1
for s in src:
nsrc='src/'+title + str(id)
nsrc = nsrc.replace('#','').replace('.','').replace(' ','')
nsrc = nsrc + '.png'
open(workdir+nsrc,"w").write(get_html(s))
html=html.replace(s,'../'+nsrc)
return html # 获取contest内容
def get_contest(c):
html=get_html("http://codeforces.com/contest/%d/problems"%c)
p=allre('class="caption">(.*?)</div>').findall(html)
if len(p)==0:
return None
title=HTMLParser.HTMLParser().unescape(p[0]) # 获取标题 html_path = workdir + 'html/[%d]%s.html'%(c,title.replace('/','_'))
flag = False
if os.path.exists(html_path):
flag = True
else:
html=allre('(<div style="text-align: center;.*)').findall(html)[0] # 获取比赛页面内容
html=down_src(html,title) #下载页面所需要的src
return (c,title,html_path,html,flag) # 存储contest内容
def save_contest(contest):
html_path=contest[2]
html=contest[3]
open(html_path,'w').write(header+html) # ---------------------------------------------------------------
# 多线程类
class crawl_contest(threading.Thread):
def __init__(this):
threading.Thread.__init__(this)
def run(this):
global begin
while begin<=end:
lock.acquire()
curid=begin
begin+=1
lock.release()
contest=get_contest(curid)
lock.acquire()
# 三种情况,1- 没有获取到页面 2 - 页面已经下载过了 3 - 正常爬取页面
if contest==None:
print "cannot crawl contest %d"%curid
elif contest[4]:
print "existed:[%d]%s"%(contest[0],contest[1])
else:
save_contest(contest)
print "crawled:[%d]%s"%(contest[0],contest[1])
lock.release()
# --------------------------------------------------------------- # ---------------------------------------------------------------
# 从控制台获取参数 python xx.py 200 300 20 xxxx ----- 5
# 0 1 2 3 4
# argv[1] -> begin
# argv[2] -> end
# argv[3] -> thread number
# argv[4] -> workdir 默认为当前目录 arglen=len(sys.argv)
if arglen<4 or arglen>5:
print "Usage:\n\t%s begin end threads [workdir]"%sys.argv[0]
exit()
if arglen==5:
workdir=sys.argv[4]
else:
workdir="./" begin=int(sys.argv[1])
end=int(sys.argv[2])
threads=int(sys.argv[3]) # 创建src与html目录
for d in ['src','html']:
d = workdir + d
if not os.path.exists(d):
print "makedirs:%s"%d
os.makedirs(d)
# --------------------------------------------------------------- # 初始化线程lock
lock = threading.RLock() #读取html头
header=open("header.html").read() # 开始工作
print "crawl contest %d to %d\n%d threads used,save in %s"%(begin,end,threads,workdir)
for i in range(threads):
crawl_contest().start()

3. 实例

我们以下载编号为200-250的contest为例:

python crawl_html.py 200 250 30

其中html保存的即为html页面,src保存的为图片等资源

我们随意打开一个页面,可以看到,效果不错。

我们再使用shell脚本,将html批量生成pdf:

./html2pdf.sh

可以看到,我们成功将html转化为pdf了。

python爬虫学习(5) —— 扒一下codeforces题面的更多相关文章

  1. python爬虫学习 —— 总目录

    开篇 作为一个C党,接触python之后学习了爬虫. 和AC算法题的快感类似,从网络上爬取各种数据也很有意思. 准备写一系列文章,整理一下学习历程,也给后来者提供一点便利. 我是目录 听说你叫爬虫 - ...

  2. python爬虫学习(1) —— 从urllib说起

    0. 前言 如果你从来没有接触过爬虫,刚开始的时候可能会有些许吃力 因为我不会从头到尾把所有知识点都说一遍,很多文章主要是记录我自己写的一些爬虫 所以建议先学习一下cuiqingcai大神的 Pyth ...

  3. Python爬虫学习:二、爬虫的初步尝试

    我使用的编辑器是IDLE,版本为Python2.7.11,Windows平台. 本文是博主原创随笔,转载时请注明出处Maple2cat|Python爬虫学习:二.爬虫的初步尝试 1.尝试抓取指定网页 ...

  4. Python爬虫学习:三、爬虫的基本操作流程

    本文是博主原创随笔,转载时请注明出处Maple2cat|Python爬虫学习:三.爬虫的基本操作与流程 一般我们使用Python爬虫都是希望实现一套完整的功能,如下: 1.爬虫目标数据.信息: 2.将 ...

  5. Python爬虫学习:四、headers和data的获取

    之前在学习爬虫时,偶尔会遇到一些问题是有些网站需要登录后才能爬取内容,有的网站会识别是否是由浏览器发出的请求. 一.headers的获取 就以博客园的首页为例:http://www.cnblogs.c ...

  6. 《Python爬虫学习系列教程》学习笔记

    http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己 ...

  7. python爬虫学习视频资料免费送,用起来非常666

    当我们浏览网页的时候,经常会看到像下面这些好看的图片,你是否想把这些图片保存下载下来. 我们最常规的做法就是通过鼠标右键,选择另存为.但有些图片点击鼠标右键的时候并没有另存为选项,或者你可以通过截图工 ...

  8. python爬虫学习笔记(一)——环境配置(windows系统)

    在进行python爬虫学习前,需要进行如下准备工作: python3+pip官方配置 1.Anaconda(推荐,包括python和相关库)   [推荐地址:清华镜像] https://mirrors ...

  9. [转]《Python爬虫学习系列教程》

    <Python爬虫学习系列教程>学习笔记 http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多. ...

随机推荐

  1. c#操作MangoDB 之MangoDB CSharp Driver驱动详解

    序言 MangoDB CSharp Driver是c#操作mongodb的官方驱动. 官方Api文档:http://api.mongodb.org/csharp/2.2/html/R_Project_ ...

  2. 【.net 深呼吸】记录WCF的通信消息

    前面老周给大伙伴们介绍了把跟踪信息写入日志文件的方法,今天咱们换个类似的话题来扯一下,对了,咱们就说说怎么把WCF的往来消息log下来吧. 尽管在现实生活中,我们不主张偷窥他人信息,不过,偷窥程序信息 ...

  3. JavaScript语言精粹--执行环境及作用域,this

    1.执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为. 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中. 虽然我们无法访问,但是解析器在处理数据时 ...

  4. 计算机程序的思维逻辑 (29) - 剖析String

    上节介绍了单个字符的封装类Character,本节介绍字符串类.字符串操作大概是计算机程序中最常见的操作了,Java中表示字符串的类是String,本节就来详细介绍String. 字符串的基本使用是比 ...

  5. Java进击C#——语法之IO操作

    本章简言 上一章我们对线程同步进行讲解.了解如何去处理可能发生的脏数据.而本章就要讲有关于C#在读取IO文件的时候,常常用到的操作类.这一章的内容会比较少.但是笔者还是总结出来让读者们有一个学习的方向 ...

  6. C#委托的一次"甜蜜"接触

    委托是个说烂了的话题,但是依旧有好多人不知道为什么要在C#中使用委托,最近有朋友也问到我这个问题,所以举例些场景,以供那些知道怎么声明委托.怎么调用却不知道为什么要用的朋友一些参考,当然也是希望验证下 ...

  7. redis成长之路——(三)

    redis连接封装 StackExchange.Redis中有一些常功能是不在database对中,例如发布订阅.获取全部key(本代码中已封装到operation中了)等,而且StackExchan ...

  8. 移动端API接口优化的术和结果

    最近一直在忙工作的事情,所以文章写得有些少. 有3-5篇文章都是写到一半然后被别的事情给打断了,所以,我得找个时间好好补补. 最近一直在关注移动端接口API的可用性问题,在移动时代这个做这个优化能产生 ...

  9. windows7 x64下maven安装和配置

    http://maven.apache.org/download.cgi下载maven 环境配置 验证配置是否成功 本地仓库配置 这是原来的配置文件: 更改为: link 离线安装 eclipse m ...

  10. 升级Centos的python为2.7(centos python 升级)

    1.首先下载python的2.7.8版本的tar包.为什么没有选择最新版本的3.4呢?因为3版本的兼容性不好.很多一些成熟的项目都是基于2.7开发的. https://www.python.org/d ...