python多线程爬虫框架_python-爬虫 多线程爬虫

多线程爬虫

今日内容

1. 并发与并行(**)

2. 多线程导致数据的不安全(**) --> 理解不了, 那就记住结论(多线程共同操作数据会导致数据不安全)

3. 多线程爬虫架构(*****)

4. 多线程爬虫的代码(*****)

1.并发与并行

1.并发: 在同一时间段内, 所有任务同时运行.

2.并行: 在同一时刻, 所有任务同时执行

2.多线程

i = 0

i += 1

i -= 1

print(i)

多线程共同操作数据会导致数据不安全

3.多线程架构图

1.url,发请求, 获取响应

2.数据解析

3.数据持久化

from threading import Thread

from threading import Lock

from queue import Queue

import requests

import pymysql

from lxml import etree

# base_url = 'http://xiaohua.zol.com.cn/youmo/%s.html'

# 爬虫类

class Sqider(Thread):

def __init__(self, sname, urlQueue, dataQueue):

super().__init__()

self.sname = sname

self.urlQueue = urlQueue

self.dataQueue = dataQueue

self.headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36'

}

# 爬取数据

def run(self, ):

base_url = 'http://xiaohua.zol.com.cn/youmo/%s.html'

while 1:

# block 代表阻塞,block为True即为阻塞。block为False为不阻塞

try:

print('%s正在爬取数据' % self.name)

page = self.urlQueue.get(block=False)

res = requests.get(url=base_url % page, headers=self.headers)

self.dataQueue.put(res.text)

print('%s提交数据完毕--' % self.name)

except:

break

# 解析类

class Parse(Thread):

def __init__(self, pname, dataQueue, conn, cursor, lock):

super().__init__()

self.pname = pname

self.dataQueue = dataQueue

self.conn = conn

self.cursor = cursor

self.lock = lock

def run(self):

# 实现数据解析的过程

print('run方法已经调用')

self.parse(self.dataQueue) # 调用parse方法

def parse(self, dQueue):

# 实现具体的解析过程

while 1:

try:

html = dQueue.get()

tree = etree.HTML(html)

li_list = tree.xpath('//li[@class="article-summary"]')

for li in li_list:

title = li.xpath('.//span[@class="article-title"]/a/text()')[0]

content = li.xpath('.//div[@class="summary-text"]//text()')

data = {'title': title, 'content': content}

with self.lock:

self.save(data)

except:

break

# 存储数据

def save(self, data):

sql = 'insert into joke values ("%s","%s")' % (data['title'], data['content'])

try:

self.cursor.execute(sql)

self.conn.commit()

print('%s存储数据成功' % self.pname)

except Exception as e:

print(e)

self.conn.rollback()

# 主函数

def main():

# 盛放url的地方 url队列

urlQueue = Queue()

for page in range(1, 101):

urlQueue.put(page)

# 放置响应数据

dataQueue = Queue()

# 开启爬虫线程

snames = ['爬虫1号', '爬虫2号', '爬虫3号']

slist = []

for sname in snames:

# 实例化线程对象

s = Sqider(sname, urlQueue, dataQueue)

# 开启线程

s.start()

slist.append(s)

for s in slist:

s.join()

# 链接数据库

conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='1234', charset='utf8',

database='xiaohua')

cursor = conn.cursor()

# 解析线程的开启

lock = Lock() # 上锁

plist = []

pnl = ['解析1号', '解析2号', '解析3号']

for pname in pnl:

p = Parse(pname, dataQueue, conn, cursor, lock)

p.start()

plist.append(p)

for p in plist:

p.join()

# 程序入口

if __name__ == '__main__':

main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值