详解爬虫模拟登陆的三种方法

摘要: 在进行爬虫时,除了常见的不用登录就能爬取的网站,还有一类需要先登录的网站。比如豆瓣、知乎,以及上一篇文章中的桔子网。这一类网站又可以分为:只需输入帐号密码、除了帐号密码还需输入或点击验证码等类型。本文以只需输入账号密码就能登录的桔子网为例,介绍模拟登录常用的 3 种方法。

  • POST 请求方法:需要在后台获取登录的 URL并填写请求体参数,然后 POST 请求登录,相对麻烦;

  • 添加 Cookies 方法:先登录将获取到的 Cookies 加入 Headers 中,最后用 GET 方法请求登录,这种最为方便;

  • Selenium 模拟登录:代替手工操作,自动完成账号和密码的输入,简单但速度比较慢。

下面,我们用代码分别实现上述 3 种方法。

1. 目标网页

这是我们要获取内容的网页:

http://radar.itjuzi.com/investevent

 

这个网页需要先登录才能看到数据信息,登录界面如下:

 

可以看到,只需要输入账号和密码就可以登录,不用输验证码,比较简单。下面我们利用一个测试账号和密码,来实现模拟登录。

2. POST 提交请求登录

首先,我们要找到 POST 请求的 URL。

有两种方法,第一种是在网页 devtools 查看请求,第二种是在 Fiddler 软件中查看。

先说第一种方法。

 

在登录界面输入账号密码,并打开开发者工具,清空所有请求,接着点击登录按钮,这时便会看到有大量请求产生。哪一个才是 POST 请求的 URL呢?这个需要一点经验,因为是登录,所以可以尝试点击带有 「login」字眼的请求。这里我们点击第四个请求,在右侧 Headers 中可以看到请求的 URL,请求方式是 POST类型,说明 URL 找对了。

 

接着,我们下拉到 Form Data,这里有几个参数,包括 identify 和 password,这两个参数正是我们登录时需要输入的账号和密码,也就是 POST 请求需要携带的参数。

 

参数构造非常简单,接下来只需要利用 Requests.post 方法请求登录网站,然后就可以爬取内容了。

下面,我们尝试用 Fiddler 获取 POST 请求。

如果你对 Fiddler 还不太熟悉或者没有电脑上没有安装,可以先了解和安装一下。

Fiddler 是位于客户端和服务器端的 HTTP 代理,也是目前最常用的 HTTP 抓包工具之一 。 它能够记录客户端和服务器之间的所有 HTTP 请求,可以针对特定的 HTTP 请求,分析请求数据、设置断点、调试 web 应用、修改请求的数据,甚至可以修改服务器返回的数据,功能非常强大,是 web 调试的利器。

Fiddler 下载地址:

https://www.telerik.com/download/fiddler

使用教程:

https://zhuanlan.zhihu.com/p/37374178

http://www.hangge.com/blog/cache/detail_1697.html

下面,我们就通过 Fiddler 截取登录请求。

当点击登录时,官场 Fiddler 页面,左侧可以看到抓取了大量请求。通过观察,第15个请求的 URL中含有「login」字段,很有可能是登录的 POST 请求。我们点击该请求,回到右侧,分别点击「inspectors」、「Headers」,可以看到就是 POST 请求,该 URL 和上面的方法获取的 URL 是一致的。

 

接着,切换到右侧的 Webforms 选项,可以看到 Body 请求体。也和上面方法中得到的一致。

 

获取到 URL 和请求体参数之后,下面就可以开始用 Requests.post 方法模拟登录了。

代码如下:

 1import requests
 2headers = {
 3    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36',
 4    }
 5data = {
 6    'identity':'irw27812@awsoo.com',   
 7    'password':'test2018',
 8}
 9url ='https://www.itjuzi.com/user/login?redirect=&flag=&radar_coupon='
10session = requests.Session()
11session.post(url,headers = headers,data = data)
12# 登录后,我们需要获取另一个网页中的内容
13response = session.get('http://radar.itjuzi.com/investevent',headers = headers)
14print(response.status_code)
15print(response.text)

使用 session.post 方法提交登录请求,然后用 session.get 方法请求目标网页,并输出 HTML代码。可以看到,成功获取到了网页内容。

 

下面,介绍第 2 种方法。

3. 获取 Cookies,直接请求登录

上面一种方法,我们需要去后台获取 POST 请求链接和参数,比较麻烦。下面,我们可以尝试先登录,获取 Cookie,然后将该 Cookie 添加到 Headers 中去,然后用 GET 方法请求即可,过程简单很多。

代码如下:

 1import requests
 2headers = {
 3    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36',
 4    'Cookie': '你的cookie',
 5}
 6url = 'https://www.itjuzi.com/user/login?redirect=&flag=&radar_coupon='
 7session = requests.Session()
 8response = session.get('http://radar.itjuzi.com/investevent', headers=headers)
 9
10print(response.status_code)
11print(response.text)

可以看到,添加了 Cookie 后就不用再 POST 请求了,直接 GET 请求目标网页即可。可以看到,也能成功获取到网页内容。

 

下面介绍第 3 种方法。

4. Selenium 模拟登录

这个方法很直接,利用 Selenium 代替手动方法去自动输入账号密码然后登录就行了。

代码如下:

 1from selenium import webdriver
 2from selenium.webdriver.common.by import By
 3from selenium.webdriver.support import expected_conditions as EC
 4from selenium.webdriver.support.wait import WebDriverWait
 5browser = webdriver.Chrome()
 6browser.maximize_window()  # 最大化窗口
 7wait = WebDriverWait(browser, 10) # 等待加载10s
 8
 9def login():
10    browser.get('https://www.itjuzi.com/user/login')
11    input = wait.until(EC.presence_of_element_located(
12        (By.XPATH, '//*[@id="create_account_email"]')))
13    input.send_keys('irw27812@awsoo.com')
14    input = wait.until(EC.presence_of_element_located(
15        (By.XPATH, '//*[@id="create_account_password"]')))
16    input.send_keys('test2018')
17    submit = wait.until(EC.element_to_be_clickable(
18        (By.XPATH, '//*[@id="login_btn"]')))
19    submit.click() # 点击登录按钮
20    get_page_index()
21
22def get_page_index():
23    browser.get('http://radar.itjuzi.com/investevent')
24    try:
25        print(browser.page_source)  # 输出网页源码
26    except Exception as e:
27        print(str(e))
28login()

这里,我们在网页中首先定位了账号节点位置:'//*[@id="create_account_email"]',然后用 input.send_keys 方法输入账号,同理,定位密码框位置并输入密码。接着定位 登录 按钮的位置://*[@id="login_btn"],然后用 submit.click() 方法实现点击登录按钮操作,从而完成登录。可以看到,也能成功获取到网页内容。

 

以上就是模拟需登录网站的几种方法。当登录进去后,就可以开始爬取所需内容了。

源代码可以在下面链接中获得:

https://github.com/makcyun/web_scraping_with_python

5. 总结:

  • 本文分别实现了模拟登录的 3 种操作方法,建议优先选择第 2 种,即先获取 Cookies 再 Get 请求直接登录的方法。

  • 本文模拟登录的网站,仅需输入账号密码,不需要获取相关加密参数,比如 Authenticity_token ,同时也无需输入验证码,所以方法比较简单。但是还有很多网站模拟登录时,需要处理加密参数、验证码输入等问题。后续将会介绍。

本文完。

  • 34
    点赞
  • 244
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
multiprocessing 是 Python 自带的一个多进程模块,可以方便地启动进程并进行进程间通信。multiprocessing 启动进程的三种方法如下: 1. 使用 Process 类启动进程 Process 类是 multiprocessing 模块中启动进程的核心类,通过创建 Process 类的实例对象并调用 start() 方法,即可启动一个新的进程。例如: ```python from multiprocessing import Process def func(): print('Hello, world!') if __name__ == '__main__': p = Process(target=func) p.start() ``` 2. 使用 Pool 类启动进程池 Pool 类可以帮助我们创建进程池,将多个进程任务分配给进程池中的进程处理。例如: ```python from multiprocessing import Pool def func(x): return x * x if __name__ == '__main__': p = Pool(4) result = p.map(func, [1, 2, 3, 4]) print(result) ``` 以上代码中,创建了一个进程池,最大进程数为 4。将任务列表 [1, 2, 3, 4] 分配给进程池中的进程处理,并通过 map() 方法返回处理结果。 3. 使用 Manager 类启动进程间通信 Manager 类可以帮助我们创建进程间共享的数据结构,例如列表、字典、队列等。例如: ```python from multiprocessing import Manager, Process def func(l): l.append('Hello, world!') if __name__ == '__main__': manager = Manager() l = manager.list() p = Process(target=func, args=(l,)) p.start() p.join() print(l) ``` 以上代码中,使用 Manager 类创建了一个共享列表 l,将其作为参数传递给子进程。子进程向列表中添加了一条记录后,主进程通过 join() 方法等待子进程执行完毕,然后打印出列表 l 的内容。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值