博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
百度贴吧 | 通用抓图脚本
阅读量:6943 次
发布时间:2019-06-27

本文共 4921 字,大约阅读时间需要 16 分钟。

多进程优势:单个进程的崩溃,不会影响其它进程

随之而来的问题是,进程之间,资源不共享,信息不共享,所以进程通讯的问题,是实现多进程协作,必须解决的问题

为解决进程间的通讯,人们常用的方法是 --> 创建一个中间人(队列),作为他们交流的中介...

以爬取某贴吧帖子中的所有图片为例:

大致需要四步

一. 获取所有的 帖子的目录

二. 根据帖子的目录,获取 帖子详情页

三. 根据 帖子详情页 的源码,获取内嵌的 图片url信息

四. 根据 图片url信息,下载图片到本地

通信图
动图_脚本运行效果
运行中
from multiprocessing import Process, Queueimport timefrom time import sleepimport requestsfrom lxml import etreeimport os, sysimport reclass BaiduTb(object):    def __init__(self, tb_name):        self.start_url = "https://tieba.baidu.com/f?ie=utf-8&kw=" + tb_name        self.q_list = Queue()        self.q_detail = Queue()        self.q_image = Queue()        self.headers = {            "User-Agent": "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) "        }        self.p1 = None        self.p2 = None        self.p3 = None        self.p4 = None    # 获取响应内容    def get_response_content(self, url):        response = requests.get(url, headers = self.headers)        print("-->",response)        return response.content    # 获取下一个网页url    def get_next_url(self, now_url):        content = self.get_response_content(now_url)        # 将响应信息转换为element对象        html = etree.HTML(content)        # 通过xpath获取下一页的链接        next_url = "http:" + html.xpath('//a[@class="next pagination-item "]/@href')[0]        return next_url    def get_list_page_urls(self, q_list):        while True:            try:                sleep(1)                q_list.put(self.start_url)                self.start_url = self.get_next_url(self.start_url)            except:                print("主程序..")    def get_detail_page_urls(self, q_list, q_detail):        while True:            sleep(1)            try:                if not q_list.empty():                    list_url = q_list.get(True)                else:                    continue            except:                print("第二进程已完成..")            content = self.get_response_content(list_url)            # 将响应信息转换为element对象            html = etree.HTML(content)            # 获取 标题 和url 列表            detail_titles_list = html.xpath('//*[@id="thread_list"]//div/div[2]/div[1]/div[1]/a/text()')            detail_urls_list = html.xpath('//*[@id="thread_list"]//div/div[2]/div[1]/div[1]/a/@href')            # 将"标题"和 url 增加到 详情页队列中            for i in range(len(detail_titles_list)):                detail_title = detail_titles_list[i]                detail_url = "https://tieba.baidu.com" + detail_urls_list[i]                temp_tuple = (detail_title, detail_url)                q_detail.put(temp_tuple)    def get_image_urls (self, q_detail, q_image):        while True:            sleep(3)            try:                detail = q_detail.get()                detail_title = detail[0]                detail_url = detail[1]            except Exception as e:                print("第三进程已完成")            # 获取详情页所有图片的url            content = self.get_response_content(detail_url)            # 将响应信息转换为element对象            html = etree.HTML(content)            # 通过xpath获取下一页的链接            image_urls = html.xpath('//cc//img/@src')            for i in range(len(image_urls)):                image_url = image_urls[i]                temp_image_info = (detail_title, image_url)                q_image.put(temp_image_info)    def save_image(self, q_image):        while True:            sleep(3)            try:                if not q_image.empty():                    image_info = q_image.get()                    image_name = re.match(r".*(.{10})", image_info[1]).group(1)                    print("图片名称为:", image_name, "图片地址为:", image_info[1], "帖子标题为:", image_info[0])                    # 尝试根据帖子名称,创建新文件夹                    try:                        os.mkdir("./%s"%(image_info[0]))                    except:                        pass                    new_file_path = "./%s/%s"%(image_info[0],image_name)                    with open(new_file_path, "wb") as f:                        data = self.get_response_content(image_info[1])                        f.write(data)                    if (self.q_list.empty()) and (self.q_detail.empty()) and (self.q_image.empty()):                        exit()            except:                print("第四进程已完成")    def run(self):        print("开始执行")        self.p1 = Process(target = self.get_list_page_urls, args=(self.q_list,))        self.p2 = Process(target = self.get_detail_page_urls, args=(self.q_list, self.q_detail,))           self.p3 = Process(target = self.get_image_urls, args=(self.q_detail, self.q_image,))        self.p4 = Process(target = self.save_image, args=(self.q_image,))        self.p1.start()        self.p2.start()        self.p3.start()        self.p4.start()        self.p1.join()        self.p2.join()        self.p3.join()        self.p4.join()def main():    name = input("请输入贴吧名称:")    beautiful_girl = BaiduTb(name)    beautiful_girl.run()if __name__ == '__main__':    main()

多进程和和多线程哪个更好用?

追求资源利用率,考虑多线程
追求程序稳定性,考虑多进程

搞专业爬虫的话,先保证网速够好,再考虑多进程还是多线程~

转载地址:http://nuonl.baihongyu.com/

你可能感兴趣的文章
【视频教程】一步步将AppBox升级到Pro版
查看>>
QNX多线程同步之Barrier(屏障)
查看>>
用Lua定制Redis命令
查看>>
使用MSTest进行单元测试
查看>>
SQL Server使用侦听器IP访问时遇到"The target principal name is incorrect. Cannot generate SSPI context"...
查看>>
Linux内核配置解析 - Boot options
查看>>
贝叶斯学习及共轭先验
查看>>
前端页面性能优化的几种方式
查看>>
Windows下安装Redis并注册为服务
查看>>
【BIEE】18_时间序列函数的使用
查看>>
从 HelloWorld 看 Java 字节码文件结构
查看>>
使用X.509数字证书加密解密实务(一)-- 证书的获得和管理
查看>>
HDU 5402 Travelling Salesman Problem(多校9 模拟)
查看>>
重装linuxserver简易流程
查看>>
思维导图软件
查看>>
Apple iOS MDM开发流程
查看>>
USB CDC & 可变形参
查看>>
mysql 的一点点记录
查看>>
为php添加pcntl扩展,多线程
查看>>
(4)Smali系列学习之Smali语法详解内部类
查看>>