基于selenium和chromedriver的爬虫

2020年7月第一次接触python和爬虫,在暑期实践课上就写了爬取知乎热榜的爬虫,总体来说是比较简单的,但是在其中也遇到了不少问题。
对于一般的网站可以直接运用python中的request库进行爬取,但是像知乎等一些比较大型的网站都有反爬虫机制,而知乎采用的是html中嵌入多个javascript的方法。
首先便是登陆的问题,对于一个爬虫新手来说,刚开始就用短信验证的方法登录确实是太为难我了
avatar
于是我便发现了下面有一个qq登陆,而且在我实验过一次后发现qq登陆只需要你输入账号和密码,于是我便开始用qq进行登录
avatar
但这时又出现了问题,出现了两个窗口,怎么才能让webdriver定位到新弹出的窗口?于是便想到了获取两个窗口的id,然后进行定位,然后就成功登陆了。
但在爬取内容上又出了不少问题,最难解决的是关于链接的爬取,链接是在<a下的一个叫做href的属性中,仅仅使用find_elements_by_xpath这一个语法是不能够解决问题的,于是还需要另一个语句get_attribute()运用这两个语句就可以成功把链接爬取出来了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import lxml
from selenium import webdriver
import time
import requests
from lxml import etree
import csv
import pandas as pd
import os
import numpy as np
def login(user, passwd):
driver = webdriver.Chrome()
# 打开登陆页面
url = 'https://www.zhihu.com/signup?next=%2F'
driver.get(url)
# 选择qq登录
driver.find_element_by_xpath('//*[@id="root"]/div/main/div/div/div/div[3]/span[2]/button[2]').click()
#获取窗口id(两个窗口)
handles=driver.window_handles
#选择登录qq的窗口
driver.switch_to_window(handles[1])
#选择窗口内嵌的框架
driver.switch_to.frame('ptlogin_iframe')
#可能需要加载,设置等待时间
time.sleep(1)
#选择账号密码登录
driver.find_element_by_id('switcher_plogin').click()
#输入账号和密码
driver.find_element_by_id('u').send_keys('2248746669')
driver.find_element_by_id('p').send_keys('020727@Dyf')
#点击登录按钮
driver.find_element_by_id('login_button').click()
#转到知乎登陆界面
driver.switch_to.window(handles[0])
time.sleep(5)
#点击热榜
driver.find_element_by_xpath('//*[@id="root"]/div/main/div/div/div[1]/div/div[1]/nav/a[3]').click()
time.sleep(5)
#获取热榜信息
a=driver.find_elements_by_xpath('//h2')
c=driver.find_elements_by_xpath('/html/body/div[1]/div/main/div/div/div[1]/div/div[2]/div/div/div[2]/section/div[2]/div')
for i,m in zip(a,c):
print(i.text)
print(m.text)
for b in driver.find_elements_by_xpath('//*[@id="TopstoryContent"]/div/div/div[2]/section/div[2]/a'):
print(b.get_attribute('href'))
d=b.get_attribute('href')
#将读取到的事件和热度保存到本地
with open('1.csv','w',encoding='utf-8-sig') as csvfile:
writer=csv.writer(csvfile)
writer.writerow(['事件','热度'])
for i,m in zip(a,c):
writer.writerows([[i.text,m.text]])
#将读取到的热榜链接保存到本地
with open('2.csv','w',encoding='utf-8-sig') as csvfile:
writer=csv.writer(csvfile)
writer.writerow(['链接'])
for b in driver.find_elements_by_xpath('//*[@id="TopstoryContent"]/div/div/div[2]/section/div[2]/a'):
writer.writerows([[b.get_attribute('href')]])
#将两个csv文件合并为一个文件
inputfile_csv_1="1.csv"
inputfile_csv_2="2.csv"
outputfile="zhihu.csv"
csv_1=pd.read_csv(inputfile_csv_1,encoding='utf-8-sig',error_bad_lines=False)
csv_2=pd.read_csv(inputfile_csv_2,encoding='utf-8-sig',error_bad_lines=False)
out_csv=pd.concat([csv_1,csv_2],axis=1)
out_csv.to_csv(outputfile,index=False,encoding='utf-8-sig')
#用户的账号密码
user = 'qq账号'
passwd = 'qq密码'
print(login(user, passwd))


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!