详情点我跳转

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

一、多线程抓取网页

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

e、启动线程

import csv
import threading
import time
import requests
import lxml
from lxml import etree
import json # 递归锁
rlock = threading.RLock()
# 设置请求头
headers = {
"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"} def getAreaList(url):
'''
获取区域列表
:param url:
:return: dict {"cityName":"cityUrl"}
'''
# 获取响应
response = requests.get(url,headers=headers).text
# 创建xml树形结构对象
mytree = lxml.etree.HTML(response)
# 分区
areaList = mytree.xpath('//div[@data-role="ershoufang"]/div/a')
#分区字典
areaDict = {}
for area in areaList:
#区域名
areaName = area.xpath('./text()')[0]
areaUrl = "https://gz.lianjia.com"+area.xpath('./@href')[0]
areaDict[areaName] = areaUrl
# print(areaName,areaUrl)
return areaDict def getPageTotal(url):
'''
获取分区页数
:param url: utl
:return: int 总页数
'''
response = requests.get(url,headers=headers).text
mytree = lxml.etree.HTML(response)
# 获取总页数
pageTotal = mytree.xpath('//div[@class="page-box house-lst-page-box"]/@page-data')[0]
pageTotal = int(json.loads(pageTotal)["totalPage"])
# print(pageTotal)
return pageTotal def getHouseInfo(area,url):
'''
获取房子信息
:param area:区域
:param url: url
:return:
'''
pageTotal = getPageTotal(url)
for page in range(1,pageTotal+1):
newurl = url+"pg%d/"%page
# print(newurl)
response = requests.get(newurl,headers=headers).text
mytree = lxml.etree.HTML(response)
houseList = mytree.xpath('//li[@class="clear"]')
print(houseList)
for house in houseList:
# 房子标题
houseTitle = house.xpath('.//div[@class="title"]/a/text()')[0]
# 房子url
houseUrl = house.xpath('.//div[@class="title"]/a/@href')[0]
# 房子地址
houseAddr = house.xpath('.//div[@class="houseInfo"]//text()')
houseAddr = ''.join(houseAddr)
# 位置信息
positionInfo = house.xpath('.//div[@class="positionInfo"]//text()')
positionInfo = ''.join(positionInfo)
# 总价
priceInfo = house.xpath('.//div[@class="totalPrice"]/span/text()')[0] + '万'
# 平方价
unitPrice = house.xpath('.//div[@class="unitPrice"]/span/text()')[0]
print(houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice)
# 保存成csv文件
with rlock:
with open('./data/'+area+'.csv','a+',encoding='utf-8',errors='ignore') as f:
writer = csv.writer(f)
writer.writerow([houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice]) if __name__ == '__main__':
#设置种子url
cityUrl = "https://gz.lianjia.com/ershoufang/"
# 获取区域列表
areaDict = getAreaList(cityUrl) threadList = []
time.clock()
for areaName,areaUrl in areaDict.items():
# 创建线程
t = threading.Thread(target=getHouseInfo,args=(areaName,areaUrl))
t.start()
threadList.append(t) # 保证线程正常结束
for t in threadList:
t.join()
print(time.clock())

二、协程抓取网页

import csv
import threading
import time
import requests
import lxml
from lxml import etree
import json import gevent
from gevent import monkey # 非阻塞型
gevent.monkey.patch_all()
# 递归锁
rlock = threading.RLock()
# 设置请求头
headers = {
"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"} def getAreaList(url):
'''
获取区域列表
:param url:
:return: dict {"cityName":"cityUrl"}
'''
# 获取响应
response = requests.get(url,headers=headers).text
# 创建xml树形结构对象
mytree = lxml.etree.HTML(response)
# 分区
areaList = mytree.xpath('//div[@data-role="ershoufang"]/div/a')
#分区字典
areaDict = {}
for area in areaList:
#区域名
areaName = area.xpath('./text()')[0]
areaUrl = "https://gz.lianjia.com"+area.xpath('./@href')[0]
areaDict[areaName] = areaUrl
# print(areaName,areaUrl)
return areaDict def getPageTotal(url):
'''
获取分区页数
:param url: utl
:return: int 总页数
'''
response = requests.get(url,headers=headers).text
mytree = lxml.etree.HTML(response)
# 获取总页数
pageTotal = mytree.xpath('//div[@class="page-box house-lst-page-box"]/@page-data')[0]
pageTotal = int(json.loads(pageTotal)["totalPage"])
# print(pageTotal)
return pageTotal def getHouseInfo(area,url):
'''
获取房子信息
:param area:区域
:param url: url
:return:
'''
pageTotal = getPageTotal(url)
for page in range(1,pageTotal+1):
newurl = url+"pg%d/"%page
# print(newurl)
response = requests.get(newurl,headers=headers).text
mytree = lxml.etree.HTML(response)
houseList = mytree.xpath('//li[@class="clear"]')
print(houseList)
for house in houseList:
# 房子标题
houseTitle = house.xpath('.//div[@class="title"]/a/text()')[0]
# 房子url
houseUrl = house.xpath('.//div[@class="title"]/a/@href')[0]
# 房子地址
houseAddr = house.xpath('.//div[@class="houseInfo"]//text()')
houseAddr = ''.join(houseAddr)
# 位置信息
positionInfo = house.xpath('.//div[@class="positionInfo"]//text()')
positionInfo = ''.join(positionInfo)
# 总价
priceInfo = house.xpath('.//div[@class="totalPrice"]/span/text()')[0] + '万'
# 平方价
unitPrice = house.xpath('.//div[@class="unitPrice"]/span/text()')[0]
print(houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice)
# 保存成csv文件
with rlock:
with open('./data/'+area+'.csv','a+',encoding='utf-8',errors='ignore') as f:
writer = csv.writer(f)
writer.writerow([houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice]) if __name__ == '__main__':
#设置种子url
cityUrl = "https://gz.lianjia.com/ershoufang/"
# 获取区域列表
areaDict = getAreaList(cityUrl) geventList = []
time.clock()
for areaName,areaUrl in areaDict.items():
# 创建协程
g = gevent.spawn(getHouseInfo,areaName,areaUrl) geventList.append(g)
# 保证协程正常结束
gevent.joinall(geventList)
print(time.clock())

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

import csv
import threading
import time
import requests
import lxml
from lxml import etree
import json
import multiprocessing
import gevent
from gevent import monkey # 非阻塞型
gevent.monkey.patch_all()
# 递归锁
rlock = threading.RLock()
# 设置请求头
headers = {
"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"} def getAreaList(url):
'''
获取区域列表
:param url:
:return: dict {"cityName":"cityUrl"}
'''
# 获取响应
response = requests.get(url,headers=headers).text
# 创建xml树形结构对象
mytree = lxml.etree.HTML(response)
# 分区
areaList = mytree.xpath('//div[@data-role="ershoufang"]/div/a')
#分区字典
areaDict = {}
for area in areaList:
#区域名
areaName = area.xpath('./text()')[0]
areaUrl = "https://gz.lianjia.com"+area.xpath('./@href')[0]
areaDict[areaName] = areaUrl
# print(areaName,areaUrl)
return areaDict def getPageTotal(url):
'''
获取分区页数
:param url: utl
:return: int 总页数
'''
response = requests.get(url,headers=headers).text
mytree = lxml.etree.HTML(response)
# 获取总页数
pageTotal = mytree.xpath('//div[@class="page-box house-lst-page-box"]/@page-data')[0]
pageTotal = int(json.loads(pageTotal)["totalPage"])
# print(pageTotal)
return pageTotal def getHouseInfo(area,url):
'''
获取房子信息
:param area:区域
:param url: url
:return:
''' def houesInfo(area,url,pageTotal):
for page in range(1,pageTotal+1):
newurl = url+"pg%d/"%page
# print(newurl)
response = requests.get(newurl,headers=headers).text
mytree = lxml.etree.HTML(response)
houseList = mytree.xpath('//li[@class="clear"]')
print(houseList)
for house in houseList:
# 房子标题
houseTitle = house.xpath('.//div[@class="title"]/a/text()')[0]
# 房子url
houseUrl = house.xpath('.//div[@class="title"]/a/@href')[0]
# 房子地址
houseAddr = house.xpath('.//div[@class="houseInfo"]//text()')
houseAddr = ''.join(houseAddr)
# 位置信息
positionInfo = house.xpath('.//div[@class="positionInfo"]//text()')
positionInfo = ''.join(positionInfo)
# 总价
priceInfo = house.xpath('.//div[@class="totalPrice"]/span/text()')[0] + '万'
# 平方价
unitPrice = house.xpath('.//div[@class="unitPrice"]/span/text()')[0]
print(houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice)
# 保存成csv文件
with rlock:
with open('./data/'+area+'.csv','a+',encoding='utf-8',errors='ignore') as f:
writer = csv.writer(f)
writer.writerow([houseTitle,houseUrl,houseAddr,positionInfo,priceInfo,unitPrice])
# 获取总页数
pageTotal = getPageTotal(url)
# 创建协程
g = gevent.spawn(houesInfo, area, url, pageTotal)
# 保证协程正常结束
gevent.joinall([g]) if __name__ == '__main__':
#设置种子url
cityUrl = "https://gz.lianjia.com/ershoufang/"
# 获取区域列表
areaDict = getAreaList(cityUrl) processList = []
time.clock()
for areaName,areaUrl in areaDict.items():
# 创建进程
p = multiprocessing.Process(target=getHouseInfo,args=(areaName,areaUrl))
p.start()
processList.append(p) # 保证进程正常结束
for p in processList:
p.join()
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. Jquery的一键上传组件OCUpload及POI解析Excel文件

    第一步:将js文件引入页面 <script type="text/javascript" src="${pageContext.request.contextPat ...

  2. Python-IndexError: list index out of range

    Error:IndexError: list index out of range Where? 对Python中有序序列进行按索引取值的时候,出现这个异常 Why? 对于有序序列: 字符串 str ...

  3. 配置hive的元数据到Mysql中

    在hive的安装目录下,进入conf目录,创建一个hive-site.xml文件 根据官方文档配置参数,拷贝数据到hive-site.xml文件中 https://cwiki.apache.org/c ...

  4. 090 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 04 使用包进行类管理(2)——导入包

    090 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...

  5. 036 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 03 嵌套if结构

    036 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 03 嵌套if结构 本文知识点:Java中的嵌套if结构 什么是嵌套if结构? 概念: 嵌套if结构 ...

  6. [POI2010]PIL-Pilots 单调队列

    [POI2010]PIL-Pilots 题意: 给定一个序列和一个数值k,求一段连续最大区间是的最大值与最小值之差小于k: 思路: 因为要维护最大值和最小值并且连续,使用两个单调队列分别同时维护最大最 ...

  7. Gearman实战第一弹:异步处理结算单

    昨天梦回jm,醒来之后看着窗外万里晴空,想大声喊一句:爷青回! 我想起之前使用gearman的岁月.不知不觉也过了快5年,想总结一篇关于gearman的技术文章算是一种对青春的祭奠,再不写的话更少有p ...

  8. c#之task与thread区别及其使用

    如果需要查看更多文章,请微信搜索公众号 csharp编程大全,需要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! ! --------------------------- ...

  9. golang不想http自动处理重定向的解决方案

    目录 前言 解决方案 结论 前言     有时候发送http请求不想让库自动帮忙处理重定向,库里面默认的是会把所有重定向都完成一遍,结果就是最后一个没有重定向的请求的结果.因此需要一种方案直接获取首次 ...

  10. day61 Pyhton 框架Django 04

    内容回顾 1.django处理请求的流程: 1. 在浏览器的地址栏输入地址,回车发get请求: 2. wsgi模块接收请求: 3. 在urls.py文件中匹配地址,找到对应的函数: 4. 执行函数,返 ...