详情点我跳转

关注公众号“轻松学编程”了解更多。

一、多线程抓取网页

流程:a.设置种子url b.获取区域列表 c.循环区域列表 d.创建线程获取页面数据

e、启动线程

  1. import csv
  2. import threading
  3. import time
  4. import requests
  5. import lxml
  6. from lxml import etree
  7. import json
  8. # 递归锁
  9. rlock = threading.RLock()
  10. # 设置请求头
  11. headers = {
  12. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"}
  13. def getAreaList(url):
  14. '''
  15. 获取区域列表
  16. :param url:
  17. :return: dict {"cityName":"cityUrl"}
  18. '''
  19. # 获取响应
  20. response = requests.get(url,headers=headers).text
  21. # 创建xml树形结构对象
  22. mytree = lxml.etree.HTML(response)
  23. # 分区
  24. areaList = mytree.xpath('//div[@data-role="ershoufang"]/div/a')
  25. #分区字典
  26. areaDict = {}
  27. for area in areaList:
  28. #区域名
  29. areaName = area.xpath('./text()')[0]
  30. areaUrl = "https://gz.lianjia.com"+area.xpath('./@href')[0]
  31. areaDict[areaName] = areaUrl
  32. # print(areaName,areaUrl)
  33. return areaDict
  34. def getPageTotal(url):
  35. '''
  36. 获取分区页数
  37. :param url: utl
  38. :return: int 总页数
  39. '''
  40. response = requests.get(url,headers=headers).text
  41. mytree = lxml.etree.HTML(response)
  42. # 获取总页数
  43. pageTotal = mytree.xpath('//div[@class="page-box house-lst-page-box"]/@page-data')[0]
  44. pageTotal = int(json.loads(pageTotal)["totalPage"])
  45. # print(pageTotal)
  46. return pageTotal
  47. def getHouseInfo(area,url):
  48. '''
  49. 获取房子信息
  50. :param area:区域
  51. :param url: url
  52. :return:
  53. '''
  54. pageTotal = getPageTotal(url)
  55. for page in range(1,pageTotal+1):
  56. newurl = url+"pg%d/"%page
  57. # print(newurl)
  58. response = requests.get(newurl,headers=headers).text
  59. mytree = lxml.etree.HTML(response)
  60. houseList = mytree.xpath('//li[@class="clear"]')
  61. print(houseList)
  62. for house in houseList:
  63. # 房子标题
  64. houseTitle = house.xpath('.//div[@class="title"]/a/text()')[0]
  65. # 房子url
  66. houseUrl = house.xpath('.//div[@class="title"]/a/@href')[0]
  67. # 房子地址
  68. houseAddr = house.xpath('.//div[@class="houseInfo"]//text()')
  69. houseAddr = ''.join(houseAddr)
  70. # 位置信息
  71. positionInfo = house.xpath('.//div[@class="positionInfo"]//text()')
  72. positionInfo = ''.join(positionInfo)
  73. # 总价
  74. priceInfo = house.xpath('.//div[@class="totalPrice"]/span/text()')[0] + '万'
  75. # 平方价
  76. unitPrice = house.xpath('.//div[@class="unitPrice"]/span/text()')[0]
  77. print(houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice)
  78. # 保存成csv文件
  79. with rlock:
  80. with open('./data/'+area+'.csv','a+',encoding='utf-8',errors='ignore') as f:
  81. writer = csv.writer(f)
  82. writer.writerow([houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice])
  83. if __name__ == '__main__':
  84. #设置种子url
  85. cityUrl = "https://gz.lianjia.com/ershoufang/"
  86. # 获取区域列表
  87. areaDict = getAreaList(cityUrl)
  88. threadList = []
  89. time.clock()
  90. for areaName,areaUrl in areaDict.items():
  91. # 创建线程
  92. t = threading.Thread(target=getHouseInfo,args=(areaName,areaUrl))
  93. t.start()
  94. threadList.append(t)
  95. # 保证线程正常结束
  96. for t in threadList:
  97. t.join()
  98. print(time.clock())

二、协程抓取网页

  1. import csv
  2. import threading
  3. import time
  4. import requests
  5. import lxml
  6. from lxml import etree
  7. import json
  8. import gevent
  9. from gevent import monkey
  10. # 非阻塞型
  11. gevent.monkey.patch_all()
  12. # 递归锁
  13. rlock = threading.RLock()
  14. # 设置请求头
  15. headers = {
  16. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"}
  17. def getAreaList(url):
  18. '''
  19. 获取区域列表
  20. :param url:
  21. :return: dict {"cityName":"cityUrl"}
  22. '''
  23. # 获取响应
  24. response = requests.get(url,headers=headers).text
  25. # 创建xml树形结构对象
  26. mytree = lxml.etree.HTML(response)
  27. # 分区
  28. areaList = mytree.xpath('//div[@data-role="ershoufang"]/div/a')
  29. #分区字典
  30. areaDict = {}
  31. for area in areaList:
  32. #区域名
  33. areaName = area.xpath('./text()')[0]
  34. areaUrl = "https://gz.lianjia.com"+area.xpath('./@href')[0]
  35. areaDict[areaName] = areaUrl
  36. # print(areaName,areaUrl)
  37. return areaDict
  38. def getPageTotal(url):
  39. '''
  40. 获取分区页数
  41. :param url: utl
  42. :return: int 总页数
  43. '''
  44. response = requests.get(url,headers=headers).text
  45. mytree = lxml.etree.HTML(response)
  46. # 获取总页数
  47. pageTotal = mytree.xpath('//div[@class="page-box house-lst-page-box"]/@page-data')[0]
  48. pageTotal = int(json.loads(pageTotal)["totalPage"])
  49. # print(pageTotal)
  50. return pageTotal
  51. def getHouseInfo(area,url):
  52. '''
  53. 获取房子信息
  54. :param area:区域
  55. :param url: url
  56. :return:
  57. '''
  58. pageTotal = getPageTotal(url)
  59. for page in range(1,pageTotal+1):
  60. newurl = url+"pg%d/"%page
  61. # print(newurl)
  62. response = requests.get(newurl,headers=headers).text
  63. mytree = lxml.etree.HTML(response)
  64. houseList = mytree.xpath('//li[@class="clear"]')
  65. print(houseList)
  66. for house in houseList:
  67. # 房子标题
  68. houseTitle = house.xpath('.//div[@class="title"]/a/text()')[0]
  69. # 房子url
  70. houseUrl = house.xpath('.//div[@class="title"]/a/@href')[0]
  71. # 房子地址
  72. houseAddr = house.xpath('.//div[@class="houseInfo"]//text()')
  73. houseAddr = ''.join(houseAddr)
  74. # 位置信息
  75. positionInfo = house.xpath('.//div[@class="positionInfo"]//text()')
  76. positionInfo = ''.join(positionInfo)
  77. # 总价
  78. priceInfo = house.xpath('.//div[@class="totalPrice"]/span/text()')[0] + '万'
  79. # 平方价
  80. unitPrice = house.xpath('.//div[@class="unitPrice"]/span/text()')[0]
  81. print(houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice)
  82. # 保存成csv文件
  83. with rlock:
  84. with open('./data/'+area+'.csv','a+',encoding='utf-8',errors='ignore') as f:
  85. writer = csv.writer(f)
  86. writer.writerow([houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice])
  87. if __name__ == '__main__':
  88. #设置种子url
  89. cityUrl = "https://gz.lianjia.com/ershoufang/"
  90. # 获取区域列表
  91. areaDict = getAreaList(cityUrl)
  92. geventList = []
  93. time.clock()
  94. for areaName,areaUrl in areaDict.items():
  95. # 创建协程
  96. g = gevent.spawn(getHouseInfo,areaName,areaUrl)
  97. geventList.append(g)
  98. # 保证协程正常结束
  99. gevent.joinall(geventList)
  100. print(time.clock())

三、协程与进程结合抓取网页

  1. import csv
  2. import threading
  3. import time
  4. import requests
  5. import lxml
  6. from lxml import etree
  7. import json
  8. import multiprocessing
  9. import gevent
  10. from gevent import monkey
  11. # 非阻塞型
  12. gevent.monkey.patch_all()
  13. # 递归锁
  14. rlock = threading.RLock()
  15. # 设置请求头
  16. headers = {
  17. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"}
  18. def getAreaList(url):
  19. '''
  20. 获取区域列表
  21. :param url:
  22. :return: dict {"cityName":"cityUrl"}
  23. '''
  24. # 获取响应
  25. response = requests.get(url,headers=headers).text
  26. # 创建xml树形结构对象
  27. mytree = lxml.etree.HTML(response)
  28. # 分区
  29. areaList = mytree.xpath('//div[@data-role="ershoufang"]/div/a')
  30. #分区字典
  31. areaDict = {}
  32. for area in areaList:
  33. #区域名
  34. areaName = area.xpath('./text()')[0]
  35. areaUrl = "https://gz.lianjia.com"+area.xpath('./@href')[0]
  36. areaDict[areaName] = areaUrl
  37. # print(areaName,areaUrl)
  38. return areaDict
  39. def getPageTotal(url):
  40. '''
  41. 获取分区页数
  42. :param url: utl
  43. :return: int 总页数
  44. '''
  45. response = requests.get(url,headers=headers).text
  46. mytree = lxml.etree.HTML(response)
  47. # 获取总页数
  48. pageTotal = mytree.xpath('//div[@class="page-box house-lst-page-box"]/@page-data')[0]
  49. pageTotal = int(json.loads(pageTotal)["totalPage"])
  50. # print(pageTotal)
  51. return pageTotal
  52. def getHouseInfo(area,url):
  53. '''
  54. 获取房子信息
  55. :param area:区域
  56. :param url: url
  57. :return:
  58. '''
  59. def houesInfo(area,url,pageTotal):
  60. for page in range(1,pageTotal+1):
  61. newurl = url+"pg%d/"%page
  62. # print(newurl)
  63. response = requests.get(newurl,headers=headers).text
  64. mytree = lxml.etree.HTML(response)
  65. houseList = mytree.xpath('//li[@class="clear"]')
  66. print(houseList)
  67. for house in houseList:
  68. # 房子标题
  69. houseTitle = house.xpath('.//div[@class="title"]/a/text()')[0]
  70. # 房子url
  71. houseUrl = house.xpath('.//div[@class="title"]/a/@href')[0]
  72. # 房子地址
  73. houseAddr = house.xpath('.//div[@class="houseInfo"]//text()')
  74. houseAddr = ''.join(houseAddr)
  75. # 位置信息
  76. positionInfo = house.xpath('.//div[@class="positionInfo"]//text()')
  77. positionInfo = ''.join(positionInfo)
  78. # 总价
  79. priceInfo = house.xpath('.//div[@class="totalPrice"]/span/text()')[0] + '万'
  80. # 平方价
  81. unitPrice = house.xpath('.//div[@class="unitPrice"]/span/text()')[0]
  82. print(houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice)
  83. # 保存成csv文件
  84. with rlock:
  85. with open('./data/'+area+'.csv','a+',encoding='utf-8',errors='ignore') as f:
  86. writer = csv.writer(f)
  87. writer.writerow([houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice])
  88. # 获取总页数
  89. pageTotal = getPageTotal(url)
  90. # 创建协程
  91. g = gevent.spawn(houesInfo, area, url, pageTotal)
  92. # 保证协程正常结束
  93. gevent.joinall([g])
  94. if __name__ == '__main__':
  95. #设置种子url
  96. cityUrl = "https://gz.lianjia.com/ershoufang/"
  97. # 获取区域列表
  98. areaDict = getAreaList(cityUrl)
  99. processList = []
  100. time.clock()
  101. for areaName,areaUrl in areaDict.items():
  102. # 创建进程
  103. p = multiprocessing.Process(target=getHouseInfo,args=(areaName,areaUrl))
  104. p.start()
  105. processList.append(p)
  106. # 保证进程正常结束
  107. for p in processList:
  108. p.join()
  109. print(time.clock())

后记

【后记】为了让大家能够轻松学编程,我创建了一个公众号【轻松学编程】,里面有让你快速学会编程的文章,当然也有一些干货提高你的编程水平,也有一些编程项目适合做一些课程设计等课题。

也可加我微信【1257309054】,拉你进群,大家一起交流学习。
如果文章对您有帮助,请我喝杯咖啡吧!

公众号

关注我,我们一起成长~~

Python爬虫练习(多线程,进程,协程抓取网页)的更多相关文章

  1. python单线程,多线程和协程速度对比

    在某些应用场景下,想要提高python的并发能力,可以使用多线程,或者协程.比如网络爬虫,数据库操作等一些IO密集型的操作.下面对比python单线程,多线程和协程在网络爬虫场景下的速度. 一,单线程 ...

  2. Python爬虫工程师必学——App数据抓取实战 ✌✌

    Python爬虫工程师必学——App数据抓取实战 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 爬虫分为几大方向,WEB网页数据抓取.APP数据抓取.软件系统 ...

  3. Python爬虫实战八之利用Selenium抓取淘宝匿名旺旺

    更新 其实本文的初衷是为了获取淘宝的非匿名旺旺,在淘宝详情页的最下方有相关评论,含有非匿名旺旺号,快一年了淘宝都没有修复这个. 可就在今天,淘宝把所有的账号设置成了匿名显示,SO,获取非匿名旺旺号已经 ...

  4. Python爬虫工程师必学APP数据抓取实战✍✍✍

    Python爬虫工程师必学APP数据抓取实战  整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大 ...

  5. Python爬虫工程师必学——App数据抓取实战

    Python爬虫工程师必学 App数据抓取实战 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大 ...

  6. 也说性能测试,顺便说python的多进程+多线程、协程

    最近需要一个web系统进行接口性能测试,这里顺便说一下性能测试的步骤吧,大概如下 一.分析接口频率 根据系统的复杂程度,接口的数量有多有少,应该优先对那些频率高,数据库操作频繁的接口进行性能测试,所以 ...

  7. python 多进程,多线程,协程

    在我们实际编码中,会遇到一些并行的任务,因为单个任务无法最大限度的使用计算机资源.使用并行任务,可以提高代码效率,最大限度的发挥计算机的性能.python实现并行任务可以有多进程,多线程,协程等方式. ...

  8. Python并发编程——多线程与协程

    Pythpn并发编程--多线程与协程 目录 Pythpn并发编程--多线程与协程 1. 进程与线程 1.1 概念上 1.2 多进程与多线程--同时执行多个任务 2. 并发和并行 3. Python多线 ...

  9. Python多进程、多线程、协程

    转载:https://www.cnblogs.com/huangguifeng/p/7632799.html 首先我们来了解下python中的进程,线程以及协程! 从计算机硬件角度: 计算机的核心是C ...

随机推荐

  1. 【typedef】Type definitions 自定义类型

  2. C++赋值兼容原则理解

    –赋值兼容原则(派生类对象是基类对象,反之不成立)–基类指针强制转换成派生类指针–派生类中重定义基类成员(同名覆盖) 假设, 一个基类 "普通人", 一个派生类 "超人& ...

  3. 借助C++探究素数的分布

    这里使用的区间是36,144,576,2304,9216,36864,147456,589824,2359296,9437184.至于这个区间是怎么得到的,感兴趣的同鞋可前往(https://www. ...

  4. 源码安装IVRE

    简介:IVRE(又名DRUNK)是一款开源的网络侦查框架工具,IVRE使用Nmap.Zmap进行主动网络探测.使用Bro.P0f等进行网络流量被动分析,探测结果存入数据库中,方便数据的查询.分类汇总统 ...

  5. 批处理文件的@echo off

    转载:https://blog.csdn.net/zl1zl2zl3/article/details/79218448  @echo off  关闭回显     @echo on  打开回显      ...

  6. JavaScript事件对象属性e.target和this的区别

    前言: Event对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象eve ...

  7. STM32之旅4——USART

    STM32之旅4--USART 串口也是用的比较多的,在STM32CubeMX中生成代码后,需要添加一些代码才可以用. drv_usart.h: #ifndef __DRV_USART_H #defi ...

  8. 多测师讲解jmeter _基本介绍_(001)高级讲师肖sir

    jmeter讲课课程 一.Jmeter简介 Jmeter是由Apache公司开发的一个纯Java的开源项目,即可以用于做接口测试也可以用于做性能测试. Jmeter具备高移植性,可以实现跨平台运行. ...

  9. 基于python实现单链表代码

    1 """ 2 linklist.py 3 单链表的构建与功能操作 4 重点代码 5 """ 6 7 class Node: 8 " ...

  10. 【数位DP】SCOI2014 方伯伯的商场之旅

    题目内容 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子. 说来也巧,位置在 \(i\) 的人面前的第 \(j\) 堆的石子的数量,刚好是 \(i\) 写成 ...