本該昨天完成的文章,拖了一天。可能是沒休息好吧,昨天的在思路以及代碼處理上存在很多問題,廢話不多說,我們一起來看一下簡書首頁數據的抓取。
抓取的信息
2.2)簡書首頁文章信息 http://www.lxweimin.com/
包括:標題,作者,發表時間,閱讀量,評論數,點贊數,打賞數,所投專題
單頁數據的獲取
我們先簡單看一下單頁數據的抓取,所謂單頁就是我們最少能獲取到的數據,那么我們就先去看一下這些信息的的加載方式
通過工具我們可以看到有一個請求連接,接著我們去看一下數據
這些信息跟我們要抓取的沒任何關系,那我們就可以直接從源碼中找這些信息了
通過分析我們看到每一個li標簽包含我們要抓取的所有信息的信息,那就可以以這個為循環點,解析第一個頁面(xpath,或者通過Beautifulsoup),這里我選擇的是xpath,我遇到了一個問題,就是評論數和閱讀量通過xpath抓不到(可能是路徑問題),我是通過正則去獲取了這兩個信息,下面給部分單頁信息獲取源碼
def getData(self,url):
print url
html = requests.get(url,headers = self.headers,cookies = self.cookies).text
response = etree.HTML(html)
item = {}
flag = 0
read = re.findall(r'ic-list-read"></i> (\d+)', html)
comment = re.findall(r'ic-list-comments"></i> (\d+)', html)
result = response.xpath('//*[@id="list-container"]/ul/li/div')
for one in result:
item[1] = one.xpath('a/text()')[0]
item[2] = one.xpath('div[1]/div/a/text()')[0]
item[3] = one.xpath('div[1]/div/span/@data-shared-at')[0]
item[4] = read[flag]
try:
item[5] = comment[flag]
except:
item[5] = u''
item[6] = one.xpath('div[2]/span/text()')[0].strip()
try:
item[7] = one.xpath('div[2]/span[2]/text()')[0].strip()
except:
item[7] = u'0'
try:
item[8] = one.xpath('div[2]/a[1]/text()')[0]
except:
item[8] = u''
flag += 1
row = [item[i] for i in range(1, 9)]
1-8分別對應之前提到的
標題,作者,發表時間,閱讀量,評論數,點贊數,打賞數,所投專題
網頁加載方式及分頁問題
我們在首頁滑動鼠標會發現,信息越來越多,但是還有一點就是可以看到URL并沒有發生變化,所以其他頁面的信息就是異步加載了,那么接著就要去抓包了
通過滑動鼠標,一段時間后我們可以看到,這個連接,但其實它已經請求了很多頁面了
這個時候我們看到,其實有兩個異步請求,已經悄悄在頁面中填充了數據
那么我們點擊閱讀更多又會有什么變化呢?
那么我們是不是可以通過,改變頁碼(page)去完成分頁呢?因為首頁和七日熱門比較類似,按照我之前爬取七日熱門的思路去抓取(spiders——簡書7日熱門(scrapy)),但是顯然精簡過得URL不能抓取首頁的信息,那么沒辦法就只能把全部的參數都懟進去試試了,首先我們來看一下除了page這個參數之外,seen_snote_ids[]參數應該在那找
我們看到第一頁并沒有帶參數, 我們再去看一下第二頁的請求信息
有很多id,那么我們應該去哪找呢,我們先去看一下第一頁的源碼
看到這些數字,是不是和第二頁的參數有關系呢,經過對比確實和第二頁的參數id一致,有了頭緒我們再去看一下第三頁的(進一步確定攜帶的參數)
經過分析,我們很巧的發現第三頁的參數是40個第二頁是20個,第一個0個,并且,第二頁的id參數,我們可以在第一頁源碼中拿到,那第三頁的是不是也可以在第二頁中看到呢?,我們去看一下第二頁源碼
因為網頁就是直接加載的,我們大概確定一下第二頁的位置,然后對比去對比第三頁的部分參數信息
大家如果仔細去對比是可以發現,確實第三頁的參數包含了第一個頁面和第二個頁面中的id信息。
現在差不多我們對這個網頁的加載方式,以及分頁方式有了進一步的理解,就是之后的每一頁除了page參數改變之外,攜帶的seen_snote_ids[]是上(幾)頁的所有id參數,那么這個到底有多少頁呢,我真的去不斷點擊加載最終,page參數停留在了15頁(seen_snote_ids[]的數量看更是非常大),并且也沒有出現閱讀更多字樣,我們來看一下
我們可以看到請求的URL的長度,參數一直在增加,所以我暫且就認為i這個是15頁,下邊給一下獲取id以及分頁URL的構造示例代碼:
1.獲取id
html = requests.get(url,headers = self.headers,cookies = self.cookies).text
response = etree.HTML(html)
ids = response.xpath('//*[@id="list-container"]/ul/li')
for one in ids:
one = 'seen_snote_ids[]=' + one.xpath('@data-note-id')[0]
2.構造頁碼
def totalPage(self):
for i in range(1,16):
data = '&'.join(self.params)
url = 'http://www.lxweimin.com/?' + data + '&page={}'.format(i)
self.getData(url)
遇到的問題+樣例源碼
1.遇到的問題
之前按照我簡書七日熱門的思路去寫,最后獲取到的都是重復數據,并且在添加id之后也是重復數據,羅羅攀 給我看了向右奔跑老大之前關于首頁分析的文章,看了之后和我的對比,感覺差不多,但是我就是出不來數據,之后各位老哥們就說可能是參數不夠吧,LEONYao老哥還說可以把參數都懟進去,滿狀態轟炸,向右奔跑老大之后說帶個cookies可行,測試之后真的可行(一個小小的cookies困擾了很長時間,沒想起來帶cookies)
2.示例代碼
# -*- coding:utf-8 -*-
from lxml import etree
import requests
import re
from Class.store_csv import CSV
class Spider(object):
headers = {
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"
}
cookies = {
'UM_distinctid': '15ac11bdff316-0ce09a4511f531-67f1a39-100200-15ac11bdff447d',
'CNZZDATA1258679142': '1034687255-1492307094-%7C1493259066',
'remember_user_token': 'W1s1MjA4MDY0XSwiJDJhJDEwJFVWVjUwbXBsS1hldkc1d0l3UG5DSmUiLCIxNDk0ODkyNTg0LjczNDM2ODgiXQ%3D%3D--f04b34c274980b45e5f7ee17c2686aeb4b567197',
'_gat': '1',
'_session_id': 'N0tvclN3V09wZ25UNFloZ0NrRTBVT3ZYQUR5VkRlV1c2Tno1bnNZc3dmQm9kQ3hmOGY4a0dFUlVLMDdPYWZJdCsydGJMaENZVU1XSHdZMHozblNhUERqaldYTHNWYXVPd2tISHVCeWJtbUFwMjJxQ3lyU2NZaTNoVUZsblV4Si94N2hRRC94MkJkUjhGNkNCYm1zVmM0R0ZqR2hFSFltZnhEcXVLbG54SlNSQU5lR0dtZ2MxOWlyYWVBMVl1a1lMVkFTYS8yQVF3bGFiR2hMblcweTU5cnR5ZTluTGlZdnFKbUdFWUYzcm9sZFZLOGduWFdnUU9yN3I0OTNZbWMxQ2UvbU5aQnByQmVoMFNjR1NmaDJJSXF6WHBYQXpPQnBVRVJnaVZVQ2xUR1p4MXNUaDhQSE80N1paLzg0amlBdjRxMU15a0JORlB1YXJ4V2g0b3hYZXpjR1NkSHVVdnA2RkgvVkJmdkJzdTg5ODhnUVRCSnN2cnlwRVJvWWc4N0lZMWhCMWNSMktMMWNERktycE0wcHFhTnYyK3ZoSWFSUFQzbkVyMDlXd2d5bz0tLThrdXQ2cFdRTTNaYXFRZm5RNWtYZUE9PQ%3D%3D--bc52e90a4f1d720f4766a5894866b3764c0482dd',
'_ga': 'GA1.2.1781682389.1492310343',
'_gid': 'GA1.2.163793537.1495583991',
'Hm_lvt_0c0e9d9b1e7d617b3e6842e85b9fb068': '1495360310,1495416048,1495516194,1495583956',
'Hm_lpvt_0c0e9d9b1e7d617b3e6842e85b9fb068': '1495583991'
}
params = []
def __init__(self):
field = ['標題', '作者', '發表時間', '閱讀量', '評論數', '點贊數', '打賞數', '所投專題']
self.write = CSV('main.csv', field)
def totalPage(self):
for i in range(1,16):
data = '&'.join(self.params)
url = 'http://www.lxweimin.com/?' + data + '&page={}'.format(i)
self.getData(url)
def getData(self,url):
print url
html = requests.get(url,headers = self.headers,cookies = self.cookies).text
response = etree.HTML(html)
ids = response.xpath('//*[@id="list-container"]/ul/li')
for one in ids:
one = 'seen_snote_ids[]=' + one.xpath('@data-note-id')[0]
self.params.append(one)
item = {}
flag = 0
read = re.findall(r'ic-list-read"></i> (\d+)', html)
comment = re.findall(r'ic-list-comments"></i> (\d+)', html)
result = response.xpath('//*[@id="list-container"]/ul/li/div')
for one in result:
item[1] = one.xpath('a/text()')[0]
item[2] = one.xpath('div[1]/div/a/text()')[0]
item[3] = one.xpath('div[1]/div/span/@data-shared-at')[0]
item[4] = read[flag]
try:
item[5] = comment[flag]
except:
item[5] = u''
item[6] = one.xpath('div[2]/span/text()')[0].strip()
try:
item[7] = one.xpath('div[2]/span[2]/text()')[0].strip()
except:
item[7] = u'0'
try:
item[8] = one.xpath('div[2]/a[1]/text()')[0]
except:
item[8] = u''
flag += 1
row = [item[i] for i in range(1, 9)]
self.write.writeRow(row)
if __name__ == "__main__":
jian = Spider()
jian.totalPage()
結果截圖
總結
現在想來,在爬取網站時,我們可以攜帶盡可能全的參數(俗話說,禮多人不怪),避免遇到我這個錯誤,scrapy版本正在寫,有興趣的可以私聊參考源碼。