吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3352|回复: 9
收起左侧

[Python 原创] 【python】多线程爬虫,边下边存,写入csv的代码

  [复制链接]
pinhai 发表于 2020-3-1 17:48
本帖最后由 pinhai 于 2020-3-1 18:18 编辑

根据https://www.52pojie.cn/thread-1117192-1-1.html的需求,编写了抓取http://jsjtw.sh.gov.cn/zjw/zhsgqyxypj/index.html网站所有的在沪建筑业(施工)企业信用评分结果 。


主要涉及了多线程爬取,多线程csv写入,xls写入,边下边存等问题,代码如下,请高手指点指点,可否继续提高 效率。ps,该网站设计的有问题,每次请求返回的是一个大table,数据比较大,下载较慢,所以想到了多线程。


[Python] 纯文本查看 复制代码
import requests
import time
from bs4 import BeautifulSoup
#from openpyxl  import load_workbook
import threading
import queue
#import sys
import csv


#写了2个写入函数,xls版本写入较慢,csv版本写入较快,推荐csv
headers={
'Host': 'ciac.zjw.sh.gov.cn',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate, br',
'X-Requested-With': 'XMLHttpRequest',
'Connection': 'keep-alive',
'Referer': 'https://ciac.zjw.sh.gov.cn/SHCreditInfoInterWeb/CreditBookAnounce/QyCreditReportIndex',
'Cookie': 'AlteonP=AJJ5Q6XdHKyfbYBZT9nwKQ$$',
}
q = queue.Queue(maxsize=10000)#存放数据的队列
pages=queue.Queue(maxsize=10000)#存放页码的队列
lock = threading.Lock()
pagestoget=50#这里改为需要抓取的总页数
g=0#已抓取页数
def main():
    wb = load_workbook("e:\\12.xlsx")
    for i in range(1,pagestoget+1):
        pages.put(i)
    t_obj = []
    w_obj=[]
    for i in range(1,11)#10个抓取进程
        t=threading.Thread(target=getdata)        
        t_obj.append(t)
    for t in t_obj:
        t.start()
    #for t in t_obj:        
     #   t.join()  #这里没有join的原因是希望边抓边存,提高效率
    time.sleep(2)
    for i in range(1,5):#4个写入进程
        #w=threading.Thread(target=writing,args=(wb,))#xls版本
        w=threading.Thread(target=writingCSV,args=(wb,))#csv版本
        w_obj.append(w)
    for w in w_obj:
        w.start()
    for w in w_obj:        
        w.join()    #这里join的原因是等待都存完了,结束主线程
    print('搞定')        
def writing(wb):#xls版本
    while(1):
        global g
        if g==pagestoget:
            break         
        print("数据队列大小:"+str(q.qsize()))
        data=q.get()
        listtemp=[]
        lock.acquire()
        #print("start writing")
        for i in data :
            listtemp.append(i.text)        
            if (data.index(i)+1)%5==0:#每5个换行1次
                #print(listtemp)
                ws = wb["Sheet1"]
                ws.append(listtemp)                
                listtemp=[]
        lock.release()
        wb.save("e:\\12.xlsx")
        g=g+1
def writingCSV(wb):#csv版本
    while(1):
        global g
        if g==pagestoget:#判断是否抓完,否则一直检测队列中是否有数据
            break         
        print("数据队列大小:"+str(q.qsize()))
        if(q.qsize()):
            data=q.get()
        else:
            time.sleep(1)#如果抓的慢,存的快,就等一等
            continue
        listtemp=[]
        lock.acquire()#锁
        with open('e:\\test.csv','a+',newline='',encoding='utf-8-sig')as f:
            fwriter=csv.writer(f)
            for i in data :
                listtemp.append(i.text)        
                if (data.index(i)+1)%5==0:#每5个换行1次
                    fwriter.writerow(listtemp)               
                    listtemp=[]
        lock.release()#解锁
        g=g+1
def getdata():
    while(pages.qsize()):
        page=pages.get()
        url='https://ciac.zjw.sh.gov.cn/SHCreditInfoInterWeb/CreditBookAnounce/GetQyCreditReportAll?page='+str(page)+'&qyNam=&qyzjCode='#构造网址
        #print(url)
        try:
            response=requests.get(url,headers=headers).json()['resultdata'].split('<div')[0].split('</thead>')[1]#获取所需数据
            print(str(page)+"get ok")
        except:
            print("page"+str(page)+"error,jump")
            pages.put(page)
            continue   
        soup = BeautifulSoup(response,"html.parser")#beautifulsoup解析数据,是个50位的大list
        data=soup.find_all('td')
        q.put(data)#存入队列
            
if __name__=='__main__':
    main()
    

免费评分

参与人数 2吾爱币 +1 热心值 +2 收起 理由
ma4907758 + 1 热心回复!
zz77244920 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
那年听风 发表于 2020-3-1 17:50
提示: 作者被禁止或删除 内容自动屏蔽
nstar1221 发表于 2020-3-1 18:46
异步io可以用协程,我觉得应该是受限于网站响应请求的速度
杨十一啊 发表于 2020-3-1 19:03
mwy1024 发表于 2020-3-1 19:17
python还不太懂, 正在学怎么处理文章这块
houbangcai 发表于 2020-3-1 19:46
学习 学习
 楼主| pinhai 发表于 2020-3-1 19:50
nstar1221 发表于 2020-3-1 18:46
异步io可以用协程,我觉得应该是受限于网站响应请求的速度

嗯嗯,我准备学一下
 楼主| pinhai 发表于 2020-3-1 19:50
杨十一啊 发表于 2020-3-1 19:03
我一般用scrapy写爬虫

早听说过这个,还不会用,准备学学
ma4907758 发表于 2020-3-1 20:51
谢谢分享。
天空宫阙 发表于 2020-3-6 15:44
不错不错
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-17 00:44

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表