使用python爬虫,requests(夹带BeautifulSoup的使用)爬取网络小说
由于本人也是初学者,算是小白一枚,这里跟大家分享一下爬取网站上的小说的过程。
第一步我们需要导入我们需要的模块,比如requests,BeautifulSoup,还有正则模块re。
import re
import requests
from bs4 import BeautifulSoup
然后我们需要找到我们需要爬取的网站,这里我选用了这个网站:*
http://www.tianxiabachang.cn
接下来就是我们需要爬出小说的html,随便在这个网站找到了一本小说,就比如说《雪中悍刀行》吧。
url = 'http://www.tianxiabachang.cn/7_7568/'
response = requests.get(url)
response.encoding = 'utf-8'
html = response.text
这样我们就能很简单的爬取到了这个小说的章节目录所在的html
但是很多时候网站都会有一定的反爬虫机制,访问几次之后我们所在的IP就会被封锁,所以我们就需要做一个简单的反反爬虫操作,那就是给你的get请求加上header,这个header可以在目标网页上找到。
比如这个就是之前我们网页的源码,(可以摁键盘上的F12或者右击鼠标点击检查,找到之后可以刷新一次)我们需要的是Request Headers下面的User-Agent,我们复制过来,然后就成了下面的情况。
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
直到目前为止我们爬取了《雪中悍刀行》的目录所在页的html了。
下一步就是找到我们爬取到的html,来进行正则处理,找到我们需要的从第一章到最后一章的所有内容
soup = BeautifulSoup(html,'html.parser')
one = soup.find("div",attrs={"id":"list"})
这样我们就得到了部分我们需要的内容:
根据这个图片,我们可以从当中写出正则表达式
pattern1 = re.compile('<dd><a href="/7_7568/(.*?)">',re.S)
pattern2 = re.compile('html">(.*?)</a></dd>',re.S)
get_url = re.findall(pattern1, str(one))
get_title = re.findall(pattern2, str(soup))
其中的pattern1 就是对文中的目录下面的网址进行的正则表达式,选取到的是7_7568(这个代表在这个网页下面的《雪中悍刀行》这本书的代码)下面的3226什么开头的数字。
而pattern2 就是网址后面的章节标题的正则表达式。
下图就是我们正则到的内容:
很明显的可以看到,前面的这些章节都是番外内容,跟我们一般看小说看的前后顺序明显不同,所以我们可以把这些不需要的删掉,直接从第一章 “小二上酒”我们爬取:
for i in range(41):
del get_url[0]
del get_title[0]
接下来我们创建一个当前文件夹下的一个txt文件来保存我们爬取的东西
with open('雪中悍刀行.txt', 'a', newline='', encoding='UTF-8-sig') as txtfile:
for i in range(len(get_url)):
reallurl = url + str(get_url[i])
# print(reallurl)
response1 = requests.get(reallurl, headers=re_header)
response1.encoding = 'utf-8'
html1 = response1.text
其中的**‘a’**是代表我们不覆盖录入,不加newline=’'的话,有可能会每个一行留一行的空白,encoding是对数据进行编码。
然后我们做了一个for循环,通过这个循环我们能重复操作,反复访问,每一章的网址下面的html,所以html1就成了每一章的html。
这个就是我们得到的一章的内容,我们对这个进行BeautifulSoup处理,因为我们只需要下面的
这个东西,所以,我们这么操作:
soup1 = BeautifulSoup(html1, "html.parser")
one = soup1.find("div",attrs={"id":"content"})
得到的one就是我们需要的每一章小说:
然后把我们得到的数据,保存到txt文件中就行
txtfile.write(str(get_title[i]) + "\n")
txtfile.write(str(one) + "\n")
以下就是全部代码,欢迎大家斧正!(我也保留了写代码时候的各种操作,大家是不是有相同的情况呢2333)
(第一次写,有什么不好的,大家留点情555)
from urllib.request import urlretrieve
import requests
import os
import re
from bs4 import BeautifulSoup
# url = 'http://www.xbiquge.la/13/13959/'
re_header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
# url = 'http://www.tianxiabachang.cn/7_7568/3226399.html'
url = 'http://www.tianxiabachang.cn/7_7568/'
response = requests.get(url,headers = re_header)
response.encoding = 'utf-8'
html = response.text
soup = BeautifulSoup(html,'html.parser')
one = soup.find("div",attrs={"id":"list"})
# print(one)
pattern1 = re.compile('<dd><a href="/7_7568/(.*?)">',re.S)
pattern2 = re.compile('html">(.*?)</a></dd>',re.S)
get_url = re.findall(pattern1, str(one))
get_title = re.findall(pattern2, str(soup))
# print(get_url)
# print(get_title)
#
for i in range(41):
del get_url[0]
del get_title[0]
# print(len(get_url), len(get_title))
#
with open('雪中悍刀行.txt', 'a', newline='', encoding='UTF-8-sig') as txtfile:
for i in range(len(get_url)):
reallurl = url + str(get_url[i])
# print(reallurl)
response1 = requests.get(reallurl, headers=re_header)
response1.encoding = 'utf-8'
html1 = response1.text
# print(html1)
soup1 = BeautifulSoup(html1, "html.parser")
one = soup1.find("div",attrs={"id":"content"})
# print(one)
# pattern3 = re.compile('<br />(.*?)<br />')
# endtxt = re.findall(pattern3, html1)
# print(html1)
# print(endtxt)
txtfile.write(str(get_title[i]) + "\n")
txtfile.write(str(one) + "\n")
print('下载第',i+1 ,'章完成')
强调文本 强调文本