使用selenium的爬蟲更加像一個人能夠做人爲的點擊滑動等操作。
在一次爬蟲中遇到了xx文庫這種,非靜態網頁,不能一次請求遍獲取全部數據,後查詢selenium能完成點擊滑動等動態操作
1.庫準備
selenium
BeautifulSoup
re
time
在使用selenium時需配合本機的瀏覽器版本下載對應的驅動最常用的兩個谷歌和搜狐的驅動器,可網上百度下載安裝。
2.構建瀏覽器實列,模擬人爲點擊與滑動。某某文庫的文檔是隻能瀏覽部分,需要點擊瀏覽更多才能加載出後面未顯示的內容。
在瀏覽器中進入開發者模式找到如上圖所示的對象,選擇他上方(或下方適應位置的對象),複製類選擇器,通過browser.find_element_by_css_selector()尋找對象,後使用browser.execute_script("arguments[0].scrollIntoView();", scroll_add_crowd_button)定位元素到視窗中,scrollIntoView()中默然參數爲true,即目標元素與視窗頂部對齊,若爲false則目標元素與底部對齊。因爲上或下對齊,xx文庫的視窗中都有頂層元素覆蓋,不能點擊到想要的元素,所以選取上(或下)適應元素將目標元素定位到視窗中位置,若目標元素不在視圖中也不能點擊。
#構建一個瀏覽器,並請求網頁
browser = webdriver.Chrome()
url = 'https://wenku.baidu.com/view/f15a777a27284b73f242507f.html'
browser.get(url)
#等待頁面加載完成,否則可能出現找不到目標元素或不能點擊等情況
time.sleep(5)
#找到目標元素上方適應位置的元素
scroll_add_crowd_button = browser.find_element_by_css_selector('#html-reader-go-more > div.banner-core-wrap.super-vip > div.doc-banner-text')
#滾動視圖到與上方元素對齊的位置
browser.execute_script("arguments[0].scrollIntoView();", scroll_add_crowd_button)
time.sleep(1)
#使用selenium的點擊,等待加載
try:
browser.find_element_by_css_selector('div.continue-to-read > div.banner-more-btn > span').click()
time.sleep(5)
except Exception as e:
print(str(e))
3.使用selenium點擊“閱讀更多”之後加載完成隱藏的數據,循環滾動滾動條,讓頁面加載每一頁的數據(該頁面共27頁,每次html只加載當前頁前後兩頁的數據),滾動一次保存html 添加進string變量,最後對string解析把解析出來的數據轉爲set去重。
html = ''
a = 0
#循環滾動滾動條到下一頁,每一次滾動都把html加到string類型的html中
while True:
a += 1
html = html + browser.page_source
browser.execute_script("window.scrollBy(0, 1050)")
time.sleep(1)
if a >= 27:
break
#html解析整理數據
soup = BeautifulSoup(html, 'html.parser')
data_list = soup.select('div.reader-txt-layer > div.ie-fix > p')
print(data_list)
a = 0
b = 0
c = 0
data_all = []
data_line = []
for i in data_list:
a = a+1
data = i.find_all(text=True)[0]
data_line.append(data)
rese_number = re.compile('\d+')
if rese_number.search(data):
b += 1
s = ','.join(data_line).replace('\n','')
data_all.append(s)
data_line = []
print(s + "_____" + str(b))
rese = re.compile('\n')
if rese.search(data):
c += 1
print('共' + c + '條數據。')
#多次保存html造成數據重複,通過set去重
data_all = set(data_all)