使用Python爬取喜歡的小說后在本地存儲為txt文件
最近在看小說時因為是在手機上在線觀看,百度了半天也沒找到可以下載的txt全集,實在沒辦法只好借助python來幫我完成需求!
準備爬取的小說名稱
蕭陽葉云舒
目標小說網站 https://www.ly990.com/
準備工具:pycharm
chrome 谷歌瀏覽器(其它瀏覽器亦可,谷歌最佳)
python3.7 環境
依賴第三方包: requests BeautifulSoup
如果沒有requests包
pip install requests
pip install beautifulsoup4
第一步:先獲取所有章節以及所有章節的鏈接
按F12即可出現開發者界面
第二步:刷新界面后,點擊Network
![圖2
第二步:在瀏覽器捕捉的眾多需求中,除去js,圖片等就找到了目標請求,如下圖所示
![圖3
可以看到該請求響應的html文件中 可以拿到所有 章節,以及每個章節的子鏈接
現在問題是我們想要的章節都是在html文件中,如何處理呢?沒關系,python中的強大的解析庫
BeautifulSoup為我們指明了方向
有關BeautifulSoup不懂的同學可以參考下這篇博文鏈接
https://blog.csdn.net/qq_36119192/article/details/82952442
我們點開其中一個章節并再次捕捉請求,就可以獲得他的請求url:https://www.ly990.com/7_7349/10769168.html;
發現是get請求,該url可以發現是 https://www.ly990.com 和 /7_7349/10769168.html 拼接而成,而/7_7349/10769168.html 就是我們第二步中圖片所示的html網頁中的信息。我們還可以看看get請求請求頭中所需要的信息,其中的path,user-agent:信息需要關注
![圖4-1
接下來整理思路 我們只要獲取所有的章節以及所有章節的子鏈接,然后我們循環去請求每個章節(請求頭中需要設置path,user-agent等),然后以追加的方式進行寫入不就可以實現完整小說的爬取了么?
話不多收直接上代碼
代碼如下
# coding
:
utf
-
8
import
re
import
os
import
time
import
random
import
requests
from
bs4
import
BeautifulSoup
def
get_contents
(
)
:
# 請求頭
headers
=
{
'authority'
:
'www.ly990.com'
,
'method'
:
'GET'
,
'path'
:
'/7_7349/'
,
'scheme'
:
'https'
,
'accept'
:
'text/html,application/xhtml+xml,application/xml;q=0.9,'
'image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3'
,
'accept-encoding'
:
'gzip, deflate, br'
,
'accept-language'
:
'zh-CN,zh;q=0.9'
,
'referer'
:
'https://www.ly990.com/7_7349/5975618.html'
,
'upgrade-insecure-requests'
:
'1'
,
'user-agent'
:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
}
fix_url
=
"https://www.ly990.com"
url
=
fix_url
+
"/7_7349/"
mysession
=
requests
.
session
(
)
# 獲取帶有所有章節目錄的響應
response
=
mysession
.
get
(
url
=
url
,
headers
=
headers
)
# 用BeautifulSoup庫解析html文件,獲取soup對象
soup
=
BeautifulSoup
(
response
.
content
.
decode
(
encoding
=
"gbk"
)
,
"lxml"
)
# soup對象根據
"dd"
標簽即可獲取所有的章節
res_list
=
soup
.
select
(
"dd"
)
return
res_list
if
__name__
==
'__main__'
:
# 調用獲取所有章節
res_list
=
get_contents
(
)
# user
-
agent列表
user_agent_list
=
[
'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko'
,
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3696.400 SLBrowser/10.0.3740.400'
,
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763'
]
# 請求每一章節時所使用的請求頭
headers
=
{
'authority'
:
'www.ly990.com'
,
'method'
:
'GET'
,
'path'
:
'/7_7349/'
,
'scheme'
:
'https'
,
'accept'
:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,'
'image/apng,*/*;q=0.8,application/signed-exchange;v=b3'
,
'accept-encoding'
:
'gzip, deflate, br'
,
'accept-language'
:
'zh-CN,zh;q=0.9'
,
'upgrade-insecure-requests'
:
'1'
,
'user-agent'
:
""
}
# 從章節列表中循環每一個章節進行請求
for
item
in
res_list
:
# soup中的string屬性可以直接獲取a標簽文字
content_name
=
item
.
a
.
string
# soup中的href屬性可以直接獲取a標簽包含的鏈接
href_content
=
item
.
a
[
'href'
]
# 更新請求頭中的path字段信息
headers
.
update
(
{
'path'
:
href_content
}
)
# 簡單的反爬蟲策略,每次隨機選擇一個user
-
agent來作為請求頭,讓服務器以為是不同的瀏覽器
headers
.
update
(
{
'user-agent'
:
random
.
choice
(
user_agent_list
)
}
)
try
:
# 組合形成最終的章節url
print
(
"url is %s"
%
(
"https://www.ly990.com"
+
href_content
)
)
# 發送
get
請求 超市時間設為
20
秒
resopnse
=
requests
.
get
(
url
=
(
"https://www.ly990.com"
+
href_content
)
,
headers
=
headers
,
timeout
=
20
)
except Exception
as
e
:
print
(
e
)
# 發生超時后隨即選擇user
-
agent再次發送請求
headers
.
update
(
{
'user-agent'
:
random
.
choice
(
user_agent_list
)
}
)
print
(
"發生異常,url是%s"
%
(
"https://www.ly990.com"
+
href_content
)
)
# 間隔
5
-
8
秒后發送請求(避免被服務器發現請求過于頻繁)
time
.
sleep
(
random
.
choice
(
[
5
,
6
,
7
,
8
]
)
)
resopnse
=
requests
.
get
(
url
=
(
"https://www.ly990.com"
+
href_content
)
,
headers
=
headers
,
timeout
=
20
)
# 判斷請求狀態
if
resopnse
.
status_code not
in
[
200
,
"200"
]
:
print
(
"the status is %s"
%
resopnse
.
status_code
)
# 如果狀態不是
200
說明請求過于頻繁應休息
5
分鐘后再開始
time
.
sleep
(
300
)
# 下面的
try
--
except是為了再次請求之前請求失敗的url(狀態碼不是
200
)
try
:
print
(
"url is %s"
%
(
"https://www.ly990.com"
+
href_content
)
)
resopnse
=
requests
.
get
(
url
=
(
"https://www.ly990.com"
+
href_content
)
,
headers
=
headers
,
timeout
=
20
)
except Exception
as
e
:
headers
.
update
(
{
'user-agent'
:
random
.
choice
(
user_agent_list
)
}
)
print
(
"發生異常,url是%s"
%
(
"https://www.ly990.com"
+
href_content
)
)
time
.
sleep
(
random
.
choice
(
range
(
10
,
30
)
)
)
resopnse
=
requests
.
get
(
url
=
(
"https://www.ly990.com"
+
href_content
)
,
headers
=
headers
,
timeout
=
20
)
# 對于正常拿到章節內容后的響應利用BeautifulSoup獲取soup對象
one_soup
=
BeautifulSoup
(
resopnse
.
content
.
decode
(
encoding
=
"gbk"
)
,
"lxml"
)
# 利用find_all方法獲取文字內容并將一些不需要的字符進行置空處理
real_content
=
str
(
one_soup
.
find_all
(
attrs
=
{
'id'
:
'content'
}
)
[
0
]
)
.
replace
(
" "
,
""
)
.
replace
(
"
"
,
""
)
.
\
replace
(
r
'
'
,
""
)
.
replace
(
"
,
""
)
.
replace
(
"
"
,
""
)
.
replace
(
r
"</p>"
,
""
)
# 在本地打開test2
.
txt文件來存儲爬取到的小說內容
with
open
(
"test2.txt"
,
"a+"
,
encoding
=
'utf-8'
)
as
f
:
# 寫入章節目錄
f
.
write
(
str
(
"\n"
+
content_name
+
"\n"
)
)
# 寫入章節內容
f
.
write
(
real_content
.
replace
(
"\n"
,
""
)
)
# 為了避免請求過于頻繁 盡可能降低請求頻率
time
.
sleep
(
random
.
choice
(
range
(
10
,
50
)
)
)
運行效果
查看爬取到的test2.txt文件
查看test2.txt文件內容
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
