python网络爬虫_Python爬虫实战之网络小说

       今天和大家分享的是python爬虫实战,由于本人最近迷上了看网络小说,学生党又穷,只能看看网络dao版小说,现在这类dao版小说网站可以说非常的多,但是所有的网站进去都可以看见一大把的广告信息,非常影响我们的阅读体验,所以我打算将dao版小说网站的小说内容通过学习到的python爬虫技术爬取下来搭建自己的小说网站,有了今天的这篇文章。

      第一步,选取目标:

      对于目标网站的选取,我们作为以为忠实的小说迷,自然要选择小说更新速度快并且访问稳定的小说网站(dao版)进行数据爬取。“笔趣阁”作为现代dao版小说网站的始祖,我们通过百度搜索相关关键词,找到了目前百度排行第一的“笔趣阁”网站,

f39847119726db116250cec622b2a404.png

      小编我只看穿越类型的小说,所以只选取了穿越类型的小说进行爬取。在我看来,爬取数据最重要的是思路,首先我们要明确我们爬取的思路,还好这种小说类型的网站网络页面都是非常的标准荷统一化,我们的大体思路如下:

1528ba5743d44e649f6b83dfe604e6f4.png

     第二步:爬虫的编写

     根据我们上面思路,我们需要用到以下模块:

Requests模块,用于发送网络请求

Lxml的etree模块,格式化我们的网页数据,便于我们使用xpath提取网页数据

Retrying模块,由于网络延迟会造成我们的数据请求失败,使用retrying模块来重新发送我们的网络请求

Tips:XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。Xpath教程:https://www.w3school.com.cn/xpath/index.asp,在百度上学习了一个小技巧,使用chrome浏览器的开发者功能,选取目标元素,在elements模块下面右键选中的模块可以直接将该元素的xpath地址复制出来。

      1.       首先创建一个发送网络请求,返回标准网页数据的函数GetUrl,代码如下:

@retry(stop_max_attempt_number=5)def GetUrl(url):    respose = requests.get(url, timeout=5)    return etree.HTML(respose.content.decode())#定义一个获取URL内容,并且返回一个被lxml模块格式化标准网页数据

      2.       定义我们的获取小说列表、小说章节以及章节内容的三个函数GetBookList,GetChapterList,GetContent代码如下:

def GetBookList(url):    content = GetUrl(url)    booklist = []    bookname = content.xpath("//*[@id='newscontent']/div[1]/ul/li[1]/span[1]/a/text()")[0]    print("开始采集《{}》".format(bookname))    for book in content.xpath("//*[@id='newscontent']/div[1]/ul/li"):        booklist.append(book.xpath("./span[1]/a/@href")[0])    return booklist#定义一个获取小说链接的函数def GetChapterList(url):    content = GetUrl(url)    chapterlist = []    for chapter in content.xpath("//*[@id='list']/dl/dd"):        chapterlist.append("http://www.xbiquge.la" + chapter.xpath("./a/@href")[0])    return chapterlist#定义一个获取小说章节的函数def GetContent(url):    temp = GetUrl(url)    chaptername=temp.xpath("//*[@class='bookname']/h1/text()")[0]    content = temp.xpath("//*[@id='content']/text()")    str = ""    for con in content:        str = str + con.replace("\r", "")    print(chaptername)    return str#定义一个获取小说章节内容的函数

根据以上的思路,我们的所有代码如下图所示

059e5f1ca1aca951f3fbb58ad190725f.png

以上代码没有写保存函数,大家可以根据自己的需求把采集下来的数据保存到文本文件或是数据库,我们一保存为txt文本为例:

with open('{}.txt'.format(i), 'wb') as f:f.write(content)

    便可按照小说的章节序号保存

模块解析

(1)     Requests模块:

1.       向网站发送请求:requests.get(url),requests.post(url),可以使用get和post方式向网站发送请求。如果用用post发送请求,则配置requests.post(url,data=post请求参数)的形式发送。

2.       可以自定义请求头信息,requests.get(url,headers=自定义请求头信息),可以自定义user-agent和cookie信息,来绕过网站的反爬手段。

3.       返回的响应正文不论什么类型,都可以用text获取。

(2)     lxml模块

此次我们运用的是lxml模块当中的etree,etree.HTML()可以用来解析字符串格式的HTML文档对象,将传进去的字符串转变成_Element对象。作为_Element对象,可以方便的使用getparent()、remove()、xpath()等方法。

(3)     Retrying模块

我们在写爬虫的过程中,经常遇到爬取失败的情况,这个时候我们一般会通过try块去进行重试,但是每次都写那么一堆try块,真的是太麻烦,所以我们用到retrying模块,被修饰的函数执行失败会自动重新执行。

stop_max_attempt_number:最大重试次数,超过这个次数会停止重试,并报异常。

wait_random_min:随机等待最小时间。

wait_random_max:随机等待最大时间。

第三,软件的实际运行:

爬虫运行效果截图

0752a024c67aaf1b4b49b5ee5e617adb.pngf4e799b8260c93c1a6ad55aa21431748.pngeeb8cd6c457cf2c9bbb99423165ff9f1.png

     本来可以一直开着我们的脚本在后台运行,但是运行一会儿我们发现脚本就报错停止了,研究了一番我们才发现由于对方访问有IP过滤的反爬措施,所以这里我们需要将我们的爬虫加入自动切换代理IP的功能。我们的requests模块支持代理功能,在网上找找几个代理,按照如下方式加入我们的代理到爬虫代码当中:

proxy_dict = {    "http": "http://username:password@hogehoge.proxy.jp:8080/",    "https": "http://username:password@hogehoge.proxy.jp:8080/"}#引入我们爬虫程序需要使用的模块@retry(stop_max_attempt_number=5)def GetUrl(url):    respose = requests.get(url, timeout=5,proxies=proxy_dict)    return etree.HTML(respose.content.decode())

      至此我们的小说爬虫便可以一直在电脑上运行了,今天的分享也到此结束,由于是爬虫新手,文章中有错误的地方也希望大家指出和谅解,谢谢大家。

7eb292385fd511313e2c8d9bee17f376.png

本期作者:汪苏彬

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

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

相关文章

java反射机制详解_JAVA反射机制详解_JSP/Java编程_互联网开发技术网_传播最新的编程技术_php361.com...

今天,下午在和朋友聊天的时候,聊起了反射这个话题。我们就从下面这个段简单的代码开始吧。这个代码输出什么,想必大部分的读者跟我一样,会很快地知道答案:0 1 2 3 4 5 6 7 8 9。事实也是如此:朋友这个时候就…

实时修改和读取webconfig

ConfigurationManager.AppSettings.Set("MailUser","3" );ConfigurationManager.AppSettings.Set("MailPassword","2");ConfigurationManager.AppSettings.Set("MailEnable","1" ); 只能临时保存实时修改webconfi…

activity 点击后传递数据给fragment_Fragment 新特性 : Fragment Result API 使用以及源码分析

原标题: Android Fragments: Fragment Result原文地址: https://proandroiddev.com/android-fragments-fragment-result......原文作者: Husayn Hakeem今年 Google 推出了 Fragment Result API 和 Activity Results API,用来取代之前的 Activity 和 Fragment 之间通…

linux动态库与静态库混合连接

在应用程序需要连接外部库的情况下,linux默认对库的连接是使用动态库,在找不到动态库的情况下再选择静态库。使用方式为: gcc test.cpp -L. -ltestlib 如果当前目录有两个库libtestlib.so libtestlib.a 则肯定是连接libtestlib.so。如果要指定…

java运算函数_Java中的数学计算函数

Math类:java.lang.Math类中包含基本的数字操作,如指数、对数、平方根和三角函数。java.math是一个包,提供用于执行任意精度整数(BigInteger)算法和任意精度小数(BigDecimal)算法的类。java.lang.Math类中包含E和PI两个静态常量,以…

从无头单链表中删除节点

#include<iostream> using namespace std;struct Node{int data;Node* next; };void deleteNode(Node* p) {p->datap->next->data; //将p后的节点的数值赋给p的data域p->nextp->next->next; //将p后的节点删除&#xff0c;即完成了删除节点p的效果…

android卡片层叠效果_ReactNative之Android绝对布局position:#x27;absolute#x27;问题

工作中会遇到各种各样的问题&#xff0c;ReactNative开发也是填坑不止。比如最近在开发需求中&#xff0c;就遇到一个问题。在一个卡片类型的右上角添加一个删除按钮。使用了绝对布局position:absolute属性&#xff0c;在Android上却无法正常显示&#xff0c;很是烦恼。有一个相…

java监听机制_详解java的事件监听机制和观察者设计模式

首先说说监听器&#xff1a;监听器就是一个实现特定接口的普通java程序&#xff0c;这个程序专门用于监听另一个java对象的方法调用或属性改变&#xff0c;当被监听对象发生上述事件后&#xff0c;监听器某个方法将立即被执 行。java的事件监听机制可概括为3点&#xff1a;1,ja…

敏捷开发的6个实战经验

在大型企业中经常是各种软件开发模式混用&#xff0c;一些采用敏捷开发&#xff0c;一些则是采用传统的瀑布式或RUP&#xff08;统一软件开发过程&#xff09;。敏捷开发&#xff0c;相对传统软件开发模式&#xff0c;它主要是针对快速变化的需求&#xff0c;不断优化管理流程&…

C++ Editbox换行问题

在EditBox中"/r/n" 换行有时是不行的。 使用&#xff1a;strFilePath.Format("File Name: %s%c%c", strFileName,0x0D,0x0A); //strFilePath.Format("File Name: %s/r/n", strFileName);转载于:https://www.cnblogs.com/mygod/archive/2012/11/1…

java 正则匹配括号是否成对_十分钟学会正则表达式

正则表达式用处挺广的&#xff0c;主要用于处理字符串。正则引擎想要在计算机语言中使用正则表达式&#xff0c;那么这门计算机语言必须要利用正则引擎去实现相应的正则库。主要的正则引擎分为以下两类&#xff1a;DFA 确定性的状态机。不使用”回溯”&#xff0c;效率高&#…

shell 脚本比较字符串相等_比较带空格的字符串相等的Shell脚本 如何比较两个.....

****************************比较带空格的字符串相等的Shell脚本***************************如果要比较的字符串中间有空格&#xff0c;可以用下面的程序(摘自《Unix Shells by Example, 3rd Edition》)name"Joe Blow"if [[ $name "Joe Blow" ]]thenpri…

Linux 下编译并安装配置 Qt

本文介绍的是Linux 下编译并安装配置 Qt&#xff0c;最近准备做 Nokia 的 Symbian,Maemo 下触摸屏开发。考虑到程序的跨平台可移植性&#xff0c;最终选择使用 Qt 开发。相对来说&#xff0c;国内关于 Qt 相关文档并不算很多。作者将 Linux 下编译并安装配置 Qt 全过程总结了…

itext jsp页面打印

最近项目中需要一个打印功能&#xff0c;需求很简单&#xff0c;只要打印出单据就可以了&#xff0c;画出一个表格&#xff0c;一些信息需要从数据库中提取 找到了免费的itext&#xff0c;可以实现我的简单的功能了 代码&#xff1a;&#xff08;打印方法&#xff09; public S…

android token机制_你真的了解16.6ms刷新机制吗?

阅读本文前&#xff0c;请您先点击上面的蓝色字体“Android扫地僧”&#xff0c;“关注”后再点击置顶公众号&#xff0c;优质干货&#xff0c;重磅资源第一时间送达。散人丶https://juejin.im/post/5ce686a46fb9a07ec754f470前言之前在整理知识的时候&#xff0c;看到android屏…

dfa2.java 原理_DFA编程练习2

题目: 请设计DFA, 使其接受全部含有奇数个1的串, 假定 ∑ {0, 1}.解:DFA可能出现两个个状态:qeven: 读入了偶数个1的串.qodd: 读入了奇数个1的串, 该状态也是终结状态(accept state).它们的状态转移图如下:编写程序, 运行效果如下:测试用例说明:0000不被上图的DFA接受1111不被…

Asp.net的HTTP请求处理过程

说明&#xff1a; &#xff08;1&#xff09;、客户端浏览器向服务器发出一个Http请求&#xff0c;此请求会被inetinfo.exe进程截获&#xff0c;然后转交给 aspnet_isapi.dll进程&#xff0c;接着它又通过Http Pipeline的管道&#xff0c;传送给aspnet_wp.exe这个进程&#xff…

ubuntu13.10 编译时 关于链接xlib 库阶段出错的问题解决

/usr/bin/ld: fmouse_main.o: undefined reference to symbol XFlush /usr/lib/i386-linux-gnu/libX11.so.6: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status make: *** [freepen_drv] 错误 1 以上为错误提示&#xff0c…

fread读取整个文件_qt如何实现大文件的加载和显示

最近研究了下如何用qt的原生控件来加载和显示大文件&#xff08;>1G&#xff09;&#xff0c;分享下一些摸索经验。下文源码&#xff1a;compilelife/loginsight​github.com文件的内存映射在开始qt部分之前&#xff0c;我们先了解一个概念——文件的内存映射。我们知道一般…

[转]listview中设置背景图片后 拉动变黑

经本人亲测有效...在Android中&#xff0c;ListView是最常用的一个控件&#xff0c;在做UI设计的时候&#xff0c;很多人希望能够改变一下它的背景&#xff0c;使他能够符合整体的UI设计&#xff0c;改变背景背很简单只需要准备一张图片然后指定属性 android:background"d…