Python 爬虫 之 阅读呼叫转移(二)

一篇博客我们成功地从网页上爬下了小说的一个章节,理所当然地,接下来我们要把整本小说都爬下来。首先,我们要把程序从原来的读完一章就结束,改成读完一章之后可以继续进行下一章的阅读。

    注意到每个小说章节的网页下面都有下一页的链接。通过查看网页源代码,稍微整理一下(  不显示了),我们可以看到这一部分的 HTML 是下面这种格式的:

[html]  view plain copy
  1. <div id="footlink">  
  2.   <script type="text/javascript" charset="utf-8" src="/scripts/style5.js"></script>  
  3.   <a href="http://www.quanben.com/xiaoshuo/0/910/59301.html">上一页</a>      
  4.   <a href="http://www.quanben.com/xiaoshuo/0/910/">返回目录</a>      
  5.   <a href="http://www.quanben.com/xiaoshuo/0/910/59303.html">下一页</a>  
  6. </div>  

     上一页  返回目录 下一页 都在一个 id 为 footlink  的 div 中,如果想要对每个链接进行匹配的话,会抓取到网页上大量的其他链接,但是 footlink 的 div 只有一个啊!我们可以把这个 div 匹配到,抓下来,然后在这个抓下来的 div  里面再匹配 <a> 的链接,这时就只有三个了。只要取最后一个链接就是下一页的 url 的,用这个 url 更新我们抓取的目标 url ,这样就能一直抓到下一页。用户阅读逻辑为每读一个章节后,等待用户输入,如果是 quit 则退出程序,否则显示下一章。


     基础知识:

     上一篇的基础知识加上 Python 的 thread 模块.


     源代码:

[python]  view plain copy
  1. # -*- coding: utf-8 -*-  
  2.   
  3. import urllib2  
  4. import re  
  5. import thread  
  6. import chardet  
  7.   
  8. class Book_Spider:  
  9.   
  10.     def __init__(self):  
  11.         self.pages = []  
  12.         self.page = 1  
  13.         self.flag = True  
  14.         self.url = "http://www.quanben.com/xiaoshuo/10/10412/2095096.html"  
  15.   
  16.     # 将抓取一个章节  
  17.     def GetPage(self):  
  18.         myUrl = self.url  
  19.         user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'  
  20.         headers = { 'User-Agent' : user_agent }  
  21.         req = urllib2.Request(myUrl, headers = headers)  
  22.         myResponse = urllib2.urlopen(req)  
  23.         myPage = myResponse.read()  
  24.   
  25.         charset = chardet.detect(myPage)  
  26.         charset = charset['encoding']  
  27.         if charset == 'utf-8' or charset == 'UTF-8':  
  28.             myPage = myPage  
  29.         else:  
  30.             myPage = myPage.decode('gb2312','ignore').encode('utf-8')  
  31.         unicodePage = myPage.decode("utf-8")  
  32.   
  33.         # 找出 id="content"的div标记  
  34.         #抓取标题  
  35.         my_title = re.search('<div.*?id="title"><h1>(.*?)</h1></div>',unicodePage,re.S)  
  36.         my_title = my_title.group(1)  
  37.         #抓取章节内容  
  38.         my_content = re.search('<div.*?id="content">(.*?)</div>',unicodePage,re.S)  
  39.         my_content = my_content.group(1)  
  40.         my_content = my_content.replace("<br />","\n")  
  41.         my_content = my_content.replace(" "," ")  
  42.   
  43.         #用字典存储一章的标题和内容  
  44.         onePage = {'title':my_title,'content':my_content}  
  45.   
  46.         #找到页面下方的连接区域  
  47.         foot_link = re.search('<div.*?id="footlink">(.*?)</div>',unicodePage,re.S)  
  48.         foot_link = foot_link.group(1)  
  49.         #在连接的区域找下一页的连接,根据网页特点为第三个  
  50.         nextUrl = re.findall(u'<a.*?href="(.*?)">(.*?)</a>',foot_link,re.S)  
  51.         nextUrl = nextUrl[2][0]  
  52.         # 更新下一次进行抓取的链接  
  53.         self.url = nextUrl  
  54.   
  55.         return onePage  
  56.   
  57.     # 用于加载章节  
  58.     def LoadPage(self):  
  59.         while self.flag:  
  60.             if(len(self.pages) - self.page < 3):  
  61.                 try:  
  62.                     # 获取新的页面  
  63.                     myPage = self.GetPage()  
  64.                     self.pages.append(myPage)  
  65.                 except:  
  66.                     print '无法连接网页!'  
  67.   
  68.     #显示一章  
  69.     def ShowPage(self,curPage):  
  70.             print curPage['title']  
  71.             print curPage['content']  
  72.             print "\n"  
  73.             user_input = raw_input("当前是第 %d 章,回车读取下一章或者输入 quit 退出:" % self.page)  
  74.             if(user_input == 'quit'):  
  75.                 self.flag = False  
  76.             print "\n"  
  77.   
  78.     def Start(self):  
  79.         print u'开始阅读......\n'  
  80.   
  81.         # 新建一个线程  
  82.         thread.start_new_thread(self.LoadPage,())  
  83.   
  84.         # 如果self的page数组中存有元素  
  85.         while self.flag:  
  86.             if self.page <= len(self.pages):  
  87.                 nowPage = self.pages[self.page-1]  
  88.                 self.ShowPage(nowPage)  
  89.                 self.page += 1  
  90.   
  91.         print u"本次阅读结束"  
  92.   
  93.   
  94. #----------- 程序的入口处 -----------  
  95. print u""" 
  96. --------------------------------------- 
  97.    程序:阅读呼叫转移 
  98.    版本:0.2 
  99.    作者:angryrookie 
  100.    日期:2014-07-07 
  101.    语言:Python 2.7 
  102.    功能:按下回车浏览下一章节 
  103. --------------------------------------- 
  104. """  
  105.   
  106. print u'请按下回车:'  
  107. raw_input(' ')  
  108. myBook = Book_Spider()  
  109. myBook.Start()  

1
在使用Python来安装geopandas包时,由于geopandas依赖于几个其他的Python库(如GDAL, Fiona, Pyproj, Shapely等),因此安装过程可能需要一些额外的步骤。以下是一个基本的安装指南,适用于大多数用户: 使用pip安装 确保Python和pip已安装: 首先,确保你的计算机上已安装了Python和pip。pip是Python的包管理工具,用于安装和管理Python包。 安装依赖库: 由于geopandas依赖于GDAL, Fiona, Pyproj, Shapely等库,你可能需要先安装这些库。通常,你可以通过pip直接安装这些库,但有时候可能需要从其他源下载预编译的进制包(wheel文件),特别是GDAL和Fiona,因为它们可能包含一些系统级的依赖。 bash pip install GDAL Fiona Pyproj Shapely 注意:在某些系统上,直接使用pip安装GDAL和Fiona可能会遇到问题,因为它们需要编译一些C/C++代码。如果遇到问题,你可以考虑使用conda(一个Python包、依赖和环境管理器)来安装这些库,或者从Unofficial Windows Binaries for Python Extension Packages这样的网站下载预编译的wheel文件。 安装geopandas: 在安装了所有依赖库之后,你可以使用pip来安装geopandas。 bash pip install geopandas 使用conda安装 如果你正在使用conda作为你的Python包管理器,那么安装geopandas和它的依赖可能会更简单一些。 创建一个新的conda环境(可选,但推荐): bash conda create -n geoenv python=3.x anaconda conda activate geoenv 其中3.x是你希望使用的Python版本。 安装geopandas: 使用conda-forge频道来安装geopandas,因为它提供了许多地理空间相关的包。 bash conda install -c conda-forge geopandas 这条命令会自动安装geopandas及其所有依赖。 注意事项 如果你在安装过程中遇到任何问题,比如编译错误或依赖问题,请检查你的Python版本和pip/conda的版本是否是最新的,或者尝试在不同的环境中安装。 某些库(如GDAL)可能需要额外的系统级依赖,如地理空间库(如PROJ和GEOS)。这些依赖可能需要单独安装,具体取决于你的操作系统。 如果你在Windows上遇到问题,并且pip安装失败,尝试从Unofficial Windows Binaries for Python Extension Packages网站下载相应的wheel文件,并使用pip进行安装。 脚本示例 虽然你的问题主要是关于如何安装geopandas,但如果你想要一个Python脚本来重命名文件夹下的文件,在原始名字前面加上字符串"geopandas",以下是一个简单的示例: python import os # 指定文件夹路径 folder_path = 'path/to/your/folder' # 遍历文件夹中的文件 for filename in os.listdir(folder_path): # 构造原始文件路径 old_file_path = os.path.join(folder_path, filename) # 构造新文件名 new_filename = 'geopandas_' + filename # 构造新文件路径 new_file_path = os.path.join(folder_path, new_filename) # 重命名文件 os.rename(old_file_path, new_file_path) print(f'Renamed "{filename}" to "{new_filename}"') 请确保将'path/to/your/folder'替换为你想要重命名文件的实际文件夹路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值