一开始,我用的是单线程,爬完整个397页数据用时,其中如果不向数据库写入是62秒左右,如果要向数据库插入文件需要82秒
后来我改成了进程池模式,4进程爬取,其中不向数据库写入用时22秒左右 ,进程池4进程向数据库写入就要122秒.
我想请问下,怎样实现不太改变结构的情况下,达到多进程应该有的速度,也就是大概应该在30秒左右就可以爬完。需要一个可实现的代码方案。
1 from bs4 import BeautifulSoup 2 import requests 3 import time 4 import pymysql 5 from multiprocessing import Pool 6 import os 7 t1=time.time() 8 9 def multiproc(i): 10 conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='123456', db='sqlxianning') 11 cursor = conn.cursor() 12 t3=time.time() 13 print('进程%s正在下载第%s页,已耗时%s'%(os.getpid(),i,t3-t1)) 14 #获取网页url 15 url='http://www.0715fc.com/plus/list.php?tid=35&TotalResult=3966&nativeplace=4000&infotype=0&keyword=&PageNo=%s'%i 16 wb_data=requests.get(url) 17 #解析页面 18 soup=BeautifulSoup(wb_data.text,'lxml') 19 titles=soup.select('#content > div.site-section > div.site-house-list.clearfix > dl > dd.fl > p:nth-of-type(1) > a') 20 areas=soup.select('#content > div.site-section > div.site-house-list.clearfix > dl > dd.h-metre.f14.bold.pa') 21 prices=soup.select('#content > div.site-section > div.site-house-list.clearfix > dl > dd.h-price.pa.f18.yahei.c_red') 22 for title,area,price in zip(titles,areas,prices): 23 title=title.get_text() 24 ti2=title[:10] 25 area=area.get_text() 26 a2=area[:-2] 27 price=price.get_text() 28 #数据入库 29 try: 30 cursor.execute('insert into user values ("%s","%s","%s")'%(ti2,a2,price)) 31 except Exception as err: 32 print(err) 33 conn.commit() 34 cursor.close() 35 conn.close() 36 37 if __name__=='__main__': 38 #建立进程池 39 p=Pool(4) 40 for i in range(1,398): 41 p.apply_async(multiproc,args=(i,)) 42 p.close() 43 p.join() 44 t2=time.time() 45 print("总共用时%s"%(t2-t1))
跟你的数据库配置有关系吧
那请教下该如何配置,或者说数据库哪里可能存在问题?单线程用的也是这个库这个表。这个应该是我把数据库的连接和关闭放在了循环里面,导致频繁连接,打开,提交事务引起的。
将数据库连接放在最前面声明,在p.join()后关闭。测试后可以在28秒至30秒之间爬完。