python获取id标签对应数据_Python--Scrapy爬虫获取简书作者ID的全部文章列表数据
最近Python大火,為了跟上時代,試著自學了下。Scrapy是一個高級的Python爬蟲框架,它不僅包含了爬蟲的特性,還可以方便的將爬蟲數據保存到csv、json等文件中。
今天我們就試著用Scrapy來爬取簡書某位作者的全部文章。
在本篇教程中,我們假定您已經安裝好Scrapy。 如若不然,請參考 安裝指南 。
1.創建項目
在開始爬取之前,我們必須創建一個新的Scrapy項目,我這里命名為jianshu_article。打開Mac終端,cd到你打算存儲代碼的目錄中,運行下列命令:
//Mac終端運行如下命令:
scrapy startproject jianshu_article
2.創建爬蟲程序
//cd到上面創建的文件目錄
cd jianshu_article
//創建爬蟲程序
scrapy genspider jianshu jianshu.com
/*
文件說明:
scrapy.cfg 項目的配置信息,主要為Scrapy命令行工具提供一個基礎的配置信息。(真正爬蟲相關的配置信息在settings.py文件中)
items.py 設置數據存儲模型,用于結構化數據,如:Django的Model
pipelines 數據處理行為,如:一般結構化的數據持久化
settings.py 配置文件,如:USER_AGENT(模擬瀏覽器,應對網站反爬),遞歸的層數、并發數,延遲下載等
spiders 爬蟲目錄,如:創建文件,編寫爬蟲規則
*/
為了方便編寫程序,我們用Pycharm打開項目,執行完上面的命令程序會自動創建目錄及文件,其中生成了一個jianshu.py的文件,后面我們主要邏輯都將寫在此文件中。
jianshu.py
3.設置數據模型
雙擊items.py文件。
找到你想爬取的簡書作者首頁,如我自己的首頁https://www.jianshu.com/u/6b14223f1b58,用谷歌瀏覽器打開,空白處鼠標右擊,單擊“檢查”進入控制臺開發者模式:
打開控制臺.png
通過分析網頁源碼,我們大概需要這些內容:
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class JianshuArticalItem(scrapy.Item):
avatar = scrapy.Field() #頭像
nickname = scrapy.Field() #昵稱
time = scrapy.Field() #發表時間
wrap_img = scrapy.Field() #封面(缺省值)
title = scrapy.Field() #標題
abstract = scrapy.Field() #正文部分顯示
read = scrapy.Field() #查看人數
comments = scrapy.Field() #評論數
like = scrapy.Field() #喜歡(點贊)
detail = scrapy.Field() #文章詳情url
pass
如此數據模型就創建好了,后面運行爬蟲的時候,我得到的數據將存進模型對應的位置。
4.分析網頁源碼,編寫爬蟲
因為本人比較懶很少寫文章,文章數比較少,為了呈現分頁的效果,我在簡書選取了一位作者CC老師_MissCC的主頁進行爬取。
我們通過分析URL可以找到一些特征:
作者的URL為:https://www.jianshu.com/u/ + 作者ID:
作者主頁URL.png
文章URL.png
雖然我們在瀏覽器直接打開作者的URL,鼠標滾輪往下滾動會動態加載下一頁直至最后一篇文章URL還是保持不變。但是作為Scrapy爬蟲貌似只能拿到第一頁,那么如何做到呢?以我個人多年的開發經驗我嘗試在URL后面拼接一個"page"參數加上頁數,果不其然,能請求到不同的數據。
拼接參數page拿到分頁數據.png
找到這些規律,我們就可以通過分析HTML源碼,拿到我們想要的數據了。
首先,我們回到jianshu.py這個文件,導入模型:
//從項目名 jianshu_article的文件items.py導入JianshuArticleItem類
from jianshu_article.items import JianshuArticleItem
設置必要參數發起首次請求:
# -*- coding: utf-8 -*-
import scrapy
from jianshu_article.items import JianshuArticleItem
class JianshuSpider(scrapy.Spider):
name = 'jianshu'
allowed_domains = ['jianshu.com']
user_id = "1b4c832fb2ca"
url = "https://www.jianshu.com/u/{0}?page=1".format(user_id)
start_urls = [
url,
]
def parse(self, response):
#用戶頭像
c = response.xpath('//div[@class="main-top"]/a[@class="avatar"]/img/@src').extract_first()
print(c)
pass
至此終端運行命令scrapy crawl jianshu,理論上可以打印網頁內容。實則不然,沒有請求到任何數據,終端會打印一些日志信息:
日志.png
不難發現,報了403的問題和HTTP status code is not handled or not allowed的問題,導致"Closing spider (finished)"爬蟲終止。通過萬能百度,我知道大概是網站做了一些相應的反爬蟲的措施導致的。對癥下藥,我們只需要在settings.py,做一些相應修改就可以了:
```
User_Agent中文名為用戶代理,簡稱 UA,它是一個特殊字符串頭,使得服務器能夠識別客戶使用的
操作系統及版本、CPU 類型、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等。
通俗點講,我們配置這個字段的目的就是為了偽裝成瀏覽器打開網頁,達到騙過目標網站的監測。
```
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'
CONCURRENT_REQUESTS = 1 #并發數
DOWNLOAD_DELAY = 5 #為了防止IP被封,我們5秒請求一次
HTTPERROR_ALLOWED_CODES = [403] #上面報的是403,就把403加入
#默認為True,就是要遵守robots.txt 的規則,這里我們改為False
ROBOTSTXT_OBEY = False
做了相應的修改,我們再次執行爬蟲命令:scrapy crawl jianshu ,看日志打印獲取到頭像。
獲取到頭像.png
既然網頁數據能爬取成功,我們后面要做的只是分析網頁源碼了,下面就不一一去分析了,體力活。當然在此之前你要對xpath有一定的了解。
下面引用Scrapy中文官網介紹:
從網頁中提取數據有很多方法。Scrapy使用了一種基于 XPath 和 CSS 表達式機制: Scrapy Selectors。 關于selector和其他提取機制的信息請參考 Selector文檔 。
這里給出XPath表達式的例子及對應的含義:
/html/head/title: 選擇HTML文檔中
標簽內的 元素/html/head/title/text(): 選擇上面提到的
元素的文字//td: 選擇所有的
元素//div[@class="mine"]: 選擇所有具有 class="mine" 屬性的 div 元素
上邊僅僅是幾個簡單的XPath例子,XPath實際上要比這遠遠強大的多。 如果您想了解的更多,我們推薦 這篇XPath教程 。
通過上面的介紹,相信你可以做接下來的爬蟲工作了,下面貼上jianshu.py的全部代碼,以供參考:
# -*- coding: utf-8 -*-
import scrapy
from jianshu_article.items import JianshuArticleItem
class JianshuSpider(scrapy.Spider):
name = 'jianshu'
allowed_domains = ['jianshu.com']
user_id = "1b4c832fb2ca" #替換此用戶ID可獲取你需要的數據,或者放開下一行的注釋
#user_id = input('請輸入作者id:\n')
url = "https://www.jianshu.com/u/{0}?page=1".format(user_id)
start_urls = [
url,
]
def parse(self, response):
# [關注,粉絲,文章]
a = response.xpath('//div[@class="main-top"]/div[@class="info"]/ul/li/div/a/p/text()').extract()
print(a)
# [字數,收獲喜歡]
b = response.xpath('//div[@class="main-top"]/div[@class="info"]/ul/li/div/p/text()').extract()
print(b)
# 大頭像
c = response.xpath('//div[@class="main-top"]/a[@class="avatar"]/img/@src').extract_first()
print(c)
# 用戶名
d = response.xpath('//div[@class="main-top"]/div[@class="title"]/a/text()').extract_first()
print(d)
# 性別
e = response.xpath('//div[@class="main-top"]/div[@class="title"]/i/@class').extract_first()
print(e)
# 獲取文章總數,計算頁數。(簡書網站默認每頁是9組數據)
temp = int(a[2])
if (temp % 9 > 0):
count = temp // 9 + 1
else:
count = temp // 9
print("總共" + str(count) + "頁")
base_url = "https://www.jianshu.com/u/{0}?page={1}"
for i in range(1, count + 1):
i = count + 1 - i #理論上正序1~count就是按順序獲取的,但是獲取的數據是倒置的,所以我們獲取count~1的數據,得到的數組就是按照網頁形式1~count頁碼排序的了
yield scrapy.Request(base_url.format(self.user_id, i), dont_filter=True, callback=self.parse_page)
#迭代返回每頁的內容
def parse_page(self, response):
for sel in response.xpath('//div[@id="list-container"]/ul/li'):
item = JianshuArticleItem()
item['wrap_img'] = sel.xpath('a/img/@src').extract_first()
item['avatar'] = sel.xpath('div//a[@class="avatar"]/img/@src').extract_first()
item['nickname'] = sel.xpath('div//a[@class="nickname"]/text()').extract_first()
item['time'] = sel.xpath('div//span[@class="time"]/@data-shared-at').extract_first()
item['title'] = sel.xpath('div/a[@class="title"]/text()').extract_first()
item['abstract'] = sel.xpath('div/p[@class="abstract"]/text()').extract_first()
item['read'] = sel.xpath('div/div[@class="meta"]/a[1]/text()').extract()[1]
item['comments'] = sel.xpath('div/div[@class="meta"]/a[2]/text()').extract()[1]
item['like'] = sel.xpath('div/div[@class="meta"]/span/text()').extract_first()
item['detail'] = sel.xpath('div/a[@class="title"]/@href').extract_first()
yield item
至此爬蟲代碼編寫完畢,如果要把獲取的數據保存下來,你可以終端執行如下命令:
/*
此命令用于把爬取的數據保存為json文件格式,當然你也可以保存為別的文件格式。
Scrapy官方列出的文件格式有如下幾種:('json', 'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle')。
溫馨提示:如果要再次爬取,最好換一個文件名或者清空數據再爬取,因為第二還是寫入上一個文件,數據不會覆蓋,
會堆積在上次獲取的下面,造成json文件格式報錯。
*/
scrapy crawl jianshu -o data.json
程序執行完后,我們可以在文件目錄看到新生成的data.json文件,雙擊可以看到我們要獲取的全部數據:
執行爬蟲獲取到的數據.png
json解析數據跟網站上的完全吻合.png
github地址:https://github.com/leesonp/jianshu_article
至此以上就是本文的全部內容,謝謝閱讀。
總結
以上是生活随笔為你收集整理的python获取id标签对应数据_Python--Scrapy爬虫获取简书作者ID的全部文章列表数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一位被信息时代遗忘的隐秘天才,一个为人类
- 下一篇: “杨振宁理论物理研究所”