selenium模拟浏览器-----爬取马蜂窝地区全部景点

为什么使用selenium

在前面的文章中,我们了解了Ajax的分析和爬取方式,但是,对于参数加密复杂的网页来说,用之前构造请求头的方法来爬取数据未免显得困难,所以这里我们选择了使用selenium。

Selenium是一个自动化测试工具,通过它我们可以驱动浏览器执行特定的动作,对于一些参数加密复杂的javaScript渲染的页面来说,抓取效果很好。采用selenium,我们可以做到可见即可爬的效果。

selenium安装(不详细介绍,只介绍步骤)

  1. 这里我们直接采用pip来安装selenium:     pip install selenium
  2. 安装Chrome以及ChromeDriver驱动:这里选择的chrome的版本需要与ChromeDriver匹配
  3. 下载好后,将ChromeDriver的可执行文件配置到环境变量中
  4. 验证安装:
  • 上面的步骤配置完成后,在终端命令行下输入Chromedriver,输出Strating.........Only   local connections are allowed,即安装成功
  • 或者创建如下python代码:
from selenium import webdriver
browser=webdriver.Chrome()

运行之后,弹出一个空白的Chrome浏览器,则证明安装成功。

爬取马蜂窝地区全部景点代码

  1. 对于selenium的一些基本知识,可以自行到selenium中文文档中学习,内容简短,充分提升自己的个人学习能力。
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from pyquery import PyQuery as pq
import time
import os
import urllib

browser=webdriver.Chrome()
wait=WebDriverWait(browser,10)
url='http://www.mafengwo.cn/jd/10206/gonglve.html'
browser.get(url)
aomeng={}

def index_page():
    try:

        #获取总页数
        page_total=browser.find_elements_by_css_selector('span.count')
        total=page_total[0].text
        total_page=total[1:3]

        for i in range(1,int(total_page)-4):
            print('正在爬取第',str(i),'页')
            #实现下一页
            submit=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.m-pagination > a.pi.pg-next')))
            submit.click()

            html=browser.page_source
            parse_page(html)
            #print(html)
    except TimeoutException:
        print('超时')

    finally:
        browser.close()

def parse_page(html):
    doc=pq(html,parser="html")
    items=doc('.bd .scenic-list.clearfix .img').parent().items()
    for item in items:
        #标题
        aomeng['title']=item.find('h3').text()
        #子页链接
        aomeng['href']=item.attr('href')
        
        #图片链接
        aomeng['img']=item.find('.img').find('img').attr('src')
        time.sleep(3)
        save_img(aomeng)
def save_img(aomeng):
    if not os.path.exists(aomeng['title']):
        os.makedirs(aomeng['title'])
    with open('{0}/{0}.{1}'.format(aomeng['title'], 'txt'), 'a',encoding='utf-8')as f:
        f.write(aomeng['href'])
        print('写入txt文件成功')
    try:
        file_path = '{0}/{0}.{1}'.format(aomeng['title'], 'jpg')
        if not os.path.exists(file_path):
            urllib.request.urlretrieve(aomeng['img'], file_path)
            print('img 存入success!')
        else:
            print('Already Download')
    except :
        print('img 存入fail!')
        pass

index_page()

运行结果:

 

 

2.也可以采用之前构造参数的方式爬取(这里引用公众号: Python绿色通道 的方法):这里我们只介绍获取数据页代码,具体的解析,自行根据需要解析:

 

先抓包,在xhr中点击一次下一页,就有生成三个页面。其中所需要的内容在router.php中。

找到这个js文件http://js.mafengwo.net/js/hotel/sign/index.js?1552035728。在第363行和第364行打上断点,然后点击下一页。

 第363行会生成一个json变量 _0xe7fex39。在第364行,首先运行这一部分:(JSON[__Ox2133f[60]](_0xe7fex39) + _0xe7fex34)即生成一个字符串类型的变量:"{"_ts":"1553500557401","params":"{\"poi_id\":\"87950\",

 

\"page\":1,\"just_comment\":1}"}c9d6618dbc657b41a66eb0af952906f1"

然后再通过函数_0xe7fex2生成32位的字符串;最通过slice(2,12)函数对其进行切割,获得2-12的字符串,这个就是_sn的值。

 

查找这个函数发现_0xe7fec函数将变量生成一个长度为4的数组;在通过_0xe7fex10函数将数组生成对应的字符串;最后将_0xe7fex15拼接起来。

 

 

而拼接后的这串字符的2-12位就是_sn值。这整个加密过程就是常说的md5加密。右边的加密结果和_0xe7fex15拼接起来的字符串是完全一样的;

 

此时生成的_sn值bc28b3ed57就是对参数进行md5加密取2-12位的结果。

得到_sn值后,评论数据就可以很容易就得到。这里要注意的是,在请求是必须把url拼接完整,否则只会返回一点点数据。另外在生成_sn时,参数qdata必须保持一致,是双引号就是双引号,有反斜杠就要有反斜杠,不然得不到正确的_sn值。

 

代码:

import hashlib
import requests

#可将t改为你想爬取的地区参数
t=1556449494051


def par(t):
    hl = hashlib.md5()
    hl.update(t)
    return hl.hexdigest()[2:12]

def get_page():
    for i in range(19):
        print('第'+str(i)+'页')
        page=str(i)

        #可将iMddid改为你想爬取的地区码
        qdata = '{"_ts":"' + str(t) + '","iMddid":"10206","iPage":"' + str(
            page) + '","iTagId":"0","sAct":"KMdd_StructWebAjax|GetPoisByTag"}c9d6618dbc657b41a66eb0af952906f1'
        sn = par(qdata.encode('utf-8'))

        url = "http://www.mafengwo.cn/ajax/router.php"
        data = {
            'sAct': 'KMdd_StructWebAjax|GetPoisByTag',
            #可将iMddid改为你想爬取的地区码
            'iMddid': '10206',
            '_ts': t,
            'iPage': page,
            'iTagId': '0',
            '_sn': sn
        }
        headers = {
            'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
            }
        response = requests.request("POST", url, headers=headers,data=data)
        print(response.text)

get_page()

 

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狼性书生

谢谢鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值