Python-爬虫 下载天涯论坛帖子

news2024/11/15 20:07:39

请添加图片描述
为了爬取的高效性,实现的过程中我利用了python的threading模块,下面是threads.py模块,定义了下载解析页面的线程,下载图片的线程以及线程池

import threading
import urllib2
import Queue
import re

thread_lock = threading.RLock()

#下载页面的一个函数,header中没有任何内容也可以顺利的下载,就省去了
def download_page(html_url):
try:
req = urllib2.Request(html_url)
response = urllib2.urlopen(req)
page = response.read()
return page
except Exception:
print ‘download %s failed’ % html_url
return None

#下载图片的一个方法,和上面的函数很像,只不过添加了一个文件头
#因为在测试的过程中发现天涯对于没有如下文件头的图片链接是不会返回正确的图片的
def download_image(image_url, referer):
try:
req = urllib2.Request(image_url)
req.add_header(‘Host’, ‘img3.laibafile.cn’)
req.add_header(‘User-Agent’, ‘Mozilla/5.0 (Windows NT 6.3; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0’)
req.add_header(‘Accept’, ‘image/png,image/*;q=0.8,*/*;q=0.5’)
req.add_header(‘Accept-Language’, ‘zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3’)
req.add_header(‘Referer’, referer)
req.add_header(‘Origin’, ‘http://bbs.tianya.cn’)
req.add_header(‘Connection’, ‘keep-alive’)
response = urllib2.urlopen(req)
image = response.read()
return image
except Exception:
print ‘download %s failed’ % image_url
return None

#下载和解析一个页面的线程类
class download_html_page(threading.Thread):
#name:线程的名字
#page_range:用户输入的页面范围
#page_contents:解析之后楼主的内容
#img_urls:解析之后楼主贴的图的链接
#html_url:输入的页面url
#first_page:第一次已经下载好的页面,主要是考虑效率,不重复下载
def __init__(self, name, page_range, page_contents, img_urls, html_url, first_page):
threading.Thread.__init__(self)
self.name = name
self.page_range = page_range
self.page_contents = page_contents
self.img_urls = img_urls

    self.html\_url = html\_url  
    self.first\_page = first\_page  
  
#判断是不是楼主的内容  
def is\_louzhu(self, s):  
    result = re.search(r'<!-- <div class="host-ico">(.\*?)</div> -->', s, re.S)  
    return (result is not None)  

#获得页面里属于楼主图片的url  
def get\_img\_url(self, s, page\_url):  
    #判断是不是楼主给其他用户的评论,如果是的话,直接过滤掉(本人从不看评论)  
    is\_louzhu\_answer = re.search(r'-{15,}<br>', s, re.S)  
    if is\_louzhu\_answer is None:  
        imgurl = re.findall(r'<img.\*?original="(?P<imgurl>.\*?)".\*?/><br>', s, flags = re.S)  

        url\_path = \[\]  
        for one\_url in imgurl:  
            self.img\_urls.put(one\_url + '|' + page\_url)  
            path = re.search('\\w+\\.jpg', one\_url).group(0)  
            url\_path.append('img/' + path)  

        segments = re.split(r'<img .\*?/><br>', s.strip())  
        content = segments\[0\].strip()  
        for i in range(len(url\_path)):  
            content += '\\n<img src = "' + url\_path\[i\] + '" />\\n<br>'  
            content += segments\[i+1\].strip()  
        return content  

#解析夜歌页面  
def parse\_page(self, html\_page, page\_url):  
    html\_page.decode('utf-8')  
    Items = re.findall(r'<div class="atl-content">(?P<islouzhu>.+?)<div class="bbs-content.\*?">(?P<content>.+?)</div>', html\_page, re.S)  
    page\_content = ''  

    for item in Items:  
        if self.is\_louzhu(item\[0\]):  
            one\_div = self.get\_img\_url(item\[1\], page\_url)  
            if one\_div is not None:  
                page\_content += one\_div  
    return page\_content  

def run(self):  
    while self.page\_range.qsize() > 0:  
        page\_number = self.page\_range.get()  
        page\_url = re.sub('-(\\d+?)\\.shtml', '-' + str(page\_number) + '.shtml', self.html\_url)  

        page\_content = ''  
        print 'thread %s is downloading %s' % (self.name, page\_url)  
        if page\_url == self.html\_url:  
            page\_content = self.parse\_page(self.first\_page, page\_url)  
        else:  
            page = download\_page(page\_url)  
            if page is not None:  
                page\_content = self.parse\_page(page, page\_url)  
        #thread\_lock.acquire()  
        #self.page\_contents\[page\_number\] = page\_content  
        #thread\_lock.release()  
        self.page\_contents.put(page\_content, page\_number)  
    self.img\_urls.put('finished')  

#下载图片的线程
class fetch_img(threading.Thread):
def __init__(self, name, img_urls, download_img):
threading.Thread.__init__(self)
self.name = name
self.img_urls = img_urls
self.download_img = download_img

def run(self):  
    while True:  
        message = self.img\_urls.get().split('|')  
        img\_url = message\[0\]  
        if img\_url == 'finished':  
            self.img\_urls.put('finished')  
            break  
        else:  
            thread\_lock.acquire()  
            if img\_url in self.download\_img:  
                thread\_lock.release()  
                continue  
            else:  
                thread\_lock.release()  
                print 'fetching image %s' % img\_url  
                referer = message\[1\]  
                image = download\_image(img\_url, referer)  
              
                image\_name = re.search('\\w+\\.jpg', img\_url).group(0)  
                with open(r'img\\%s' % image\_name, 'wb') as img:  
                    img.write(image)  
                thread\_lock.acquire()  
                self.download\_img.add(img\_url)  
                thread\_lock.release()  

#定义了一个线程池
class thread_pool:
def __init__(self, page_range, page_contents, html_url, first_page):
self.page_range = page_range
self.page_contents = page_contents
self.img_urls = Queue.Queue()
self.html_url = html_url
self.first_page = first_page
self.download_img = set()

    self.page\_thread\_pool = \[\]  
    self.image\_thread\_pool = \[\]  
      
def build\_thread(self, page, image):  
    for i in range(page):  
        t = download\_html\_page('page thread%d' % i, self.page\_range, self.page\_contents,  
                                self.img\_urls, self.html\_url, self.first\_page)  
        self.page\_thread\_pool.append(t)  
    for i in range(image):  
        t = fetch\_img('image thread%d' % i, self.img\_urls, self.download\_img)  
        self.image\_thread\_pool.append(t)  
      
def all\_start(self):  
    for t in self.page\_thread\_pool:  
        t.start()  
    for t in self.image\_thread\_pool:  
        t.start()  
  
def all\_join(self):  
    for t in self.page\_thread\_pool:  
        t.join()  
    for t in self.image\_thread\_pool:  
        t.join()  

下面是主线程的代码:

# -*- coding: utf-8 -*-
import re
import Queue
import threads

if __name__ == ‘__main__’:
html_url = raw_input('enter the url: ')
html_page = threads.download_page(html_url)

max\_page = 0  
title = ''  
if html\_page is not None:  
    search\_title = re.search(r'<span class="s\_title"><span style="\\S+?">(?P<title>.+?)</span></span>', html\_page, re.S)  
    title = search\_title.groupdict()\['title'\]  

    search\_page = re.findall(r'<a href="/post-\\S+?-\\d+?-(?P<page>\\d+?)\\.shtml">(?P=page)</a>', html\_page, re.S)  
    for page\_number in search\_page:  
        page\_number = int(page\_number)  
        if page\_number > max\_page:  
            max\_page = page\_number  
              
print 'title:%s' % title  
print 'max page number: %s' % max\_page  
  
start\_page = 0  
while start\_page < 1 or start\_page > max\_page:  
    start\_page = input('input the start page number:')  
      
end\_page = 0  
while end\_page < start\_page or end\_page > max\_page:  
    end\_page = input('input the end page number:')  
      
page\_range = Queue.Queue()  
for i in range(start\_page, end\_page + 1):  
    page\_range.put(i)  

page\_contents = {}  
thread\_pool = threads.thread\_pool(page\_range, page\_contents, html\_url, html\_page)  
thread\_pool.build\_thread(1, 1)  
thread\_pool.all\_start()  
thread\_pool.all\_join()  

本文仅作项目练习,且勿商用!!!

由于文章篇幅有限,文档资料内容较多,需要这些文档的朋友,可以加小助手微信免费获取,【保证100%免费】,中国人不骗中国人。
请添加图片描述
全套Python学习资料分享:
一、Python所有方向的学习路线
Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述
在这里插入图片描述
二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,还有环境配置的教程,给大家节省了很多时间。
在这里插入图片描述
三、全套PDF电子书
书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。
在这里插入图片描述
四、入门学习视频全套
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。
在这里插入图片描述
在这里插入图片描述
五、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述
在这里插入图片描述
今天就分享到这里啦,感谢大家收看!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1861098.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

上电相位确定性:使用多芯片同步

将多个数字信号处理 (DSP) 块、宽带数模转换器 (DAC) 和宽带模数转换器 (ADC) 集成到单个单片芯片中&#xff0c;现在可以卸载耗电的 FPGA 资源&#xff0c;以允许更小的占地面积、更低的功耗、增加通道数的平台&#xff0c;能够以比以前更高的速率进行采样。伴随这一新功能而来…

【大数据开发语言Scala的入门教程】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

井盖位移传感器:给井盖装上“大脑”

你是否曾经在深夜回家时&#xff0c;因为路上一个不起眼的井盖而心惊胆战&#xff1f;或者因为某个井盖缺失&#xff0c;导致车辆受损、行人受伤&#xff1f;这些看似微小的问题&#xff0c;其实都隐藏着巨大的安全隐患。 旭华智能针对这一问题&#xff0c;研制了井盖位移传感器…

多种驱鸟设备,在电力安全中各显神通

多种驱鸟设备&#xff0c;在电力安全中各显神通 鸟类对电力的危险是一个不容忽视的问题&#xff0c;尤其是在电力设施密集的区域。随着人类对自然环境的不断开发和利用&#xff0c;鸟类与电力设施之间的接触也日益频繁&#xff0c;由此引发的安全隐患和事故也屡见不鲜。 具体…

【详细教程】如何使用YOLOv10进行图片与视频的目标检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

基于SaaS平台的iHRM管理系统测试学习

目录 1、登录模块 2、员工管理模块 3、Postmannewman软件的安装&#xff0c;学习 1、Postman的使用 2、Postman断言 1、断言状态码&#xff08;重要&#xff09; 2、断言包含某个字符串&#xff08;contains string&#xff09; 3、断言等于某个字符串(equal string) …

【多通道卷积终结篇,通俗易懂,清晰必读】

作为常识&#xff0c; 1、卷积层 输出特征图通道数 卷积核个数 与输入特征图通道数无关&#xff0c; 2、多卷积核处理多通道特征图的机制过程如下&#xff1a; 本文的参考资料为知乎&#xff1a;一文读懂Faster RCNN。 对于多通道图像多卷积核做卷积&#xff0c;计算方式如…

中兴光猫破解telnet配置命令汇总

中兴光猫telnet配置命令汇总 | LogDicthttps://www.logdict.com/archives/zhong-xing-guang-mao-telnetpei-zhi-ming-ling-hui-zong

Pikachu靶场--SSRF

参考借鉴&#xff1a;pikachu靶场练习——SSRF详解_pikachu ssrf-CSDN博客 SSRF(curl) 先了解一下curl curl是一个非常实用的、用来与服务器之间传输数据的工具&#xff1b;支持的协议包括 (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, PO…

【技术指南】稳压器(电压调节器):原理、类型及其实际用用案例

电压调节器&#xff08;稳压器&#xff09;是一种电子器件或电路&#xff0c;用于控制电路中的电压水平&#xff0c;以确保在电源电压波动或负载变化时&#xff0c;输出电压能够保持在设定的稳定水平。它们通常用于各种电子设备和电源系统中&#xff0c;以提供稳定的电压供应。…

AMEYA360代理品牌江苏润石:RS8661/2/4系列高压精密低噪声运算放大器

继RS8651/2/4系列高压精密低噪声运算放大器成功推向市场&#xff0c;润石科技再次成功量产RS8661/2/4系列高压精密低噪声运算放大器。 RS8661/2/4系列产品将工作电压提升到最高36V(18V)、失调电压进一步优化到5μV、在工业现场数据采集、各种仪器仪表测量设备\分析设备上有着广…

QT中的样式表.qss文件

一、前言 qt中样式表的改变有几种方法&#xff0c;第一种就是直接在ui界面对应的组件右键修改样式表&#xff0c;还有一种就是直接在程序里面修改样式表&#xff0c;我知道的还有一种就是qss文件&#xff0c;这个文件就是将在程序中写的修改样式表的语句写道qss文件中&#xff…

ROS CDK魔法书:点亮博客上云新技能(Python篇)

引言 在数字世界的浩瀚海洋中&#xff0c;信息与数据如同戏剧中的主角&#xff0c;舞动着无形的旋律&#xff0c;构建起信息时代的交响乐。而在这其中&#xff0c;作为一位技术领域的探索者&#xff0c;你的使命便是挥舞着编码的魔杖&#xff0c;创造和守护着这些宝贵的数字灵…

游戏AI的创造思路-技术基础-深度学习(1)

他来了&#xff0c;他来啦&#xff0c;后面歌词忘了~~~~~ 开谈深度学习&#xff0c;填上一点小坑&#xff0c;可又再次开掘大洞 -.-b 目录 1. 定义 2. 深度学习的发展历史和典型事件 3. 深度学习常用算法 3.1. 卷积神经网络&#xff08;CNN&#xff09; 3.1.1. 算法形成过…

前端必会--浏览器的工作原理与实践

进程与线程 线程 线程分为单线程和多线程 线程是不能单独存在的&#xff0c;它是由进程来启动和管理的。 进程 一个进程就是一个程序的运行实例。详细解释就是&#xff0c;启动一个程序的时候&#xff0c;操作系统会为该程序创建一块内存&#xff0c;用来存放代码、运行中的…

OpenAI扩大版图,收购Mac协作应用巨擘Multi

Multi&#xff0c;这款专为macOS用户打造的多人协作应用&#xff0c;凭借其卓越的低延迟实时协作功能&#xff0c;如共享光标、绘图和键盘控制&#xff0c;在业界享有盛誉。如今&#xff0c;OpenAI宣布成功收购Multi&#xff0c;以进一步扩大其技术生态。Multi公司将停止运营&a…

ppt忘记保存怎么恢复?

朋友们大家好&#xff0c;我是热爱分享电脑知识的资源伙伴~接下来&#xff0c;别忘了点赞、收藏并关注资源伙伴&#xff01;如果你在使用PowerPoint时忘记保存演示文稿&#xff0c;突然关闭程序或电脑出现故障&#xff0c;不用太担心。 PowerPoint和大多数现代Office应用程序都…

将本地项目托管到Github或码云中

最按照打开页面的步骤&#xff0c;一步步生成公钥就&#xff1a; 按照提示完成三次回车&#xff0c;即可生成 ssh key 到C:\Users\登录用户名.ssh下找到文件d_rsa.pub &#xff0c;打开就可以获取到public key 将id_rsa.pub文件中的内容全部复制到设置/SSH页面中&#xff1a; 单…

PWN练习---Stack_1

pwn123 题源&#xff1a;ctfshow–pwn123 知识点&#xff1a;逻辑漏洞引发的数组越界&#xff0c;导致任意地址写&#xff0c;覆盖返回地址。 主要源码 查看ida存在后面函数&#xff0c;可以劫持ctfshow函数的返回值到backdoor获得shell。 查看case 1代码发现并未对数组赋值的…

ThreadLocal 源码浅析

前言 多线程在访问同一个共享变量时很可能会出现并发问题&#xff0c;特别是在多线程对共享变量进行写入时&#xff0c;那么除了加锁还有其他方法避免并发问题吗&#xff1f;本文将详细讲解 ThreadLocal 的使用及其源码。 一、什么是 ThreadLocal&#xff1f; ThreadLocal 是 J…