Python学习日记12|用python3多进程批量下载pdf文件

今天是2016年6月9日,也是农历的端午节。

难得的小长假,转眼就到学期末,忙了一学期大概大家或回家过端午或在宿舍休息调养吧,8点25到实验室的时候只有一个从广西大学来学院进修的教授已经开始了一天的工作。自己是觉得没什么特别,所有的节日能让人开心就好,即使没有粽子吃。

Anyway, 还是想说一声:端午节快乐~~


最近实习还一直没有着落,周一的面试是已经gg了,然后又开始投简历以求暑假有个去处,而不至于落单无事可做,尽管自己口头上一直说着无所谓。

这次的任务是下载上海清算网( http://www.shclearing.com/xxpl/fxpl/ )上前五页中的pdf附件。自己大约琢磨了两天才搞定,最开始以为可以像下载常规的pdf文件文件一样,直接获得pdf文件的链接地址然后用retrieve函数即可完成,但是发现pdf文件的路径是有javascript脚本控制的,你根本拿不到文件的链接地址。

于是开始看能不能构造路径,发现还是行不通,再用fiddler去监控点击下载时发生了什么,这时才有了一点眉目:在点击pdf下载时,是有提交post请求的,传入的了两个参数分别是filename和descname。这时才恍然大悟,像这种点击下载的文件,你要模拟这个点击行为,一般应该就是一个post请求。

再说一下知道是提交post请求后实际操作时有几点要注意:
1.提交到post请求中的参数,通过查看源码后发现是可以用BesutifulSoup配合正则表达式从源码中来直接提取的,正则表达式一般就用re.search(),或者re.findall()

2.提交的filename和descname参数必须先转成URL编码,这是通过fiddler截取到的form表单中发现的,所以又引入urllib库中的parse,再使用parse.quote(text)函数来实现将两个参数转化为URL编码。(自己操作时quote()函数的用法是采用的python3中的语法,若是在python2.x版本中则是直接用urllib.quote(text)即可,但是,但是python2.x版本关于中文编码真的有很多问题,动不动就报错,所以果断没有用python2.x版本

3.在上述基础上提交了filename和descname参数,如何将pdf保存下来,由于pdf文件比较大,有的达到10M,因此这里会用到 Response.iter_content()的使用,有固定的用法,实现的功能是以流的形式保存较大的文件。具体可以参考。
( http://stackoverflow.com/questions/16694907/how-to-download-large-file-in-python-with-requests-py )

4.要再说一点的就是有时候用requests.get()去请求网址时,加上headers虽说是为了伪装成浏览器进行访问,但有时反而会没有反应,去掉headers后反而就直接出了结果,这是自己不解的地方。

最后贴上代码和抓取结果(243个pdf文件,最大有24M),如下:


#!/usr/bin/env python
# _*_ coding: utf-8 _*_

import requests
from bs4 import BeautifulSoup
from urllib import parse
import re
import time
from multiprocessing import Pool

headers={
    'Host': 'www.shclearing.com',
    'Connection': 'keep-alive',
    'Content-Length': '478',
    'Cache-Control': 'max-age=0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Origin': 'http://www.shclearing.com',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.8',
    'Cookie': '_ga=GA1.2.1076225437.1465265795; JSESSIONID=24XcXXCb1bkkKWnKn1LLNBqGTR8qnfmcmf3p5T2pw2TwpNCytnfp!301927905; HDSESSIONID=fhwLXXLPrBqXwsvCyqKL1lCbp5QmGDxxGJ4wd8vrfhr2ksgJcpvf!1660475047; Hm_lvt_d885bd65f967ea9372fc7200bc83fa81=1465223724; Hm_lpvt_d885bd65f967ea9372fc7200bc83fa81=1465354426'
   }

url1='http://www.shclearing.com/xxpl/fxpl/index.html'
url2=['http://www.shclearing.com/xxpl/fxpl/index_{}.html'.format(str(i)) for i in range(1,5,1)]
url2.insert(0,url1)

links=[]
host='http://www.shclearing.com/xxpl/fxpl/'
def get_link_list(url):
    for item in url:
        web_data=requests.get(item)
        soup=BeautifulSoup(web_data.text,'lxml')
        list=soup.select('ul.list li a')
        for item in list:
            link=host+item.get('href').split('./')[1]
            links.append(link)



FileName=[]
DownName=[]
DownName1=[]   #DownName1用于存放转码后的名称
def get_contents(link):
    web_data=requests.get(link)
    soup=BeautifulSoup(web_data.text,'lxml')
    contents=soup.select('#content > div.attachments > script')[0].get_text()
    a=str(re.findall(r"fileNames = '(.*?)'",contents,re.M)[0])
    b=str(re.findall(r"descNames = '(.*?)'",contents,re.M)[0])
    FileName=a.replace('./','').split(';;')
    DownName=b.split(';;')    #先用正则表达式提取出后面post中要用到的两个参数,但是要将中文转化为对应的URL编码
    for item in DownName:
        a=parse.quote(item)
        DownName1.append(a)
    print(FileName,'\\n',DownName,'\\n',DownName1)

    for i,j,k in zip(FileName,DownName1,DownName):
        download_file(i,j,k)

# link='http://www.shclearing.com/xxpl/fxpl/cp/201606/t20160608_159680.html'
# get_contents(link)
# print('The pdf have been downloaded successfully !')


def download_file(a,b,c):
    data={
    'FileName':a,
    'DownName':b }

    local_filename = c
    post_url='http://www.shclearing.com/wcm/shch/pages/client/download/download.jsp'
    time.sleep(0.5)  #限制下载的频次速度,以免被封
    # NOTE the stream=True parameter
    r = requests.post(post_url, data=data, headers=headers, stream=True)
    with open(local_filename, 'wb') as f:
      for chunk in r.iter_content(chunk_size=1024):  # 1024 是一个比较随意的数,表示分几个片段传输数据。
          if chunk: # filter out keep-alive new chunks
              f.write(chunk)
              f.flush() #刷新也很重要,实时保证一点点的写入。
    return local_filename



if __name__=='__main__':
    get_link_list(url2)
    pool=Pool()
    pool.map(get_contents,links)
    print('The documents have been downloaded successfully !')

如果要将下载下来的文档的保存的路径存入mysql中,需要再加上下面的语句:
#conn=pymysql.connect(host='localhost',user='root',passwd='root',db='mysql',charset='utf8')
#cursor = conn.cursor()
#cursor.execute('CREATE TABLE root (id int auto_increment primary key,content varchar(100))')
以及在download_file(a,b,c)函数中的return local_filename语句前加上:
cursor.execute('insert into root(content) values (%s)',local_filename)

抓取结果截图.PNG
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容