python爬虫实战演示

python爬虫实战演示

文章目录

  • python爬虫实战演示
    • 猫眼专业版实时票房数据获取
    • 石头阅读模拟登陆
    • 设置代理ip
    • 爬取瓜子二手车交易信息
    • 爬取豆瓣top250
    • selenium行为链实战

猫眼专业版实时票房数据获取

网址:http://piaofang.maoyan.com/dashboard

错误方法1:

import requests
url = 'http://piaofang.maoyan.com/dashboard'
resp = requests.get(url)
print(resp.content.decode('utf-8'))

点开“检查网页源代码”,发现输出和源代码不一样

问题出在请求头上,连User-agent都没有,稍微走点心的网站都知道你是爬虫了

Ps.user-agent是什么:user-agent会告诉网站,访问者是通过什么工具来请求的,如果是爬虫请求,一般会拒绝;如果是用户浏览器,就会应答。我们在浏览器里获取的user-agent添加到爬虫中,网站检测这项数据时会把它当成你自己用的那个浏览器,以起到瞒天过海的作用。

错误方法2:

import requests
url = 'http://piaofang.maoyan.com/dashboard'
headers = {
      # 添加一个请求头
    'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'
}
resp = requests.get(url,headers=headers)
print(resp.content.decode('utf-8'))

这下输出和网页源代码一样了,兴高采烈找数据,发现没有

原来是因为猫眼专业版的数据是实时更新的,因此它没有保存在静态的网页结构里,而是通过json文件实时发送,所以我们在网页源代码中是找不到数据的,数据在哪呢?

python爬虫实战演示_第1张图片

点开“检查”,在Network里你会发现,网页在不停的请求文件,选中右边的Response,仔细一找,数据就在里面

当然,如果你觉得麻烦,这里推荐一个格式解析工具,可以自动把json文件里的代码以更美观的角度呈现。

在线的json解析工具:https://www.json.cn/

所以,我们请求静态网页的链接,是找不到数据的,而把链接换成发送数据包的链接,就可以得到数据了。

python爬虫实战演示_第2张图片

正确方法:

import requests

# 使用json文件里的url
url = 'http://piaofang.maoyan.com/dashboard-ajax?orderType=0&uuid=176e6479baec8-0cc8072b9a3fd4-171d4b58-13c680-176e6479bafc8&riskLevel=71&optimusCode=10&_token=eJxNkctqw0AMRf9l1sKRRvOyIYtAoaTQRUPaTchi8qgTSuLgmNJS%2Bu%2BVJi4tGO7x1cOS%2FGX6%2Bc40COZ935vGUIVVMGCGq2koEHmk6DlhALP98yySxTqC2fQvd6ZZEXECcdbqLMRYkXMINeIa%2FiGjPJozlxRzGIZLM5lcjrl7zee2OuXuM5%2BrbXea7PL1sOlyv5NJjBScllrAkQHF4RiBVJP0K8rgiyZIqjVDXTQBWQGHDigUiCNQDVZ7OGtHYAZbQhxGcBG4hLwF5gI1cAkFcaJCRHDlEzrDDTz4kixTeB3DI0PkAgGiVnkrB7mBBULdyTMBldG8XIvYKXnxSi8fZIGou%2Fmoh056lDc9imgedfh9f5T%2FKKnXY3sW2j98LJ%2Fb%2BWx2384WT9Op%2Bf4B3HBuKQ%3D%3D'

headers = {
     
    'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'
}
resp = requests.get(url,headers=headers)
print(resp.content.decode('utf-8'))

一些其他的动态网页,可能并不是实时更新,但也是采用同样的数据显示方式,这就需要你仔细的找一下数据到底藏在哪个文件里,点开Response后从上往下捋就行了。

当然你也可以使用selenium方法去模拟浏览器的行为,在这里就不细说了


石头阅读模拟登陆

石头阅读是一款免费的小说阅读器,书库覆盖面广,资源丰富,可以免费看各类需要付费的小说,堪称白嫖党的利器,趁此机会安利一下

网址:https://www.stoneread.com/

登陆在右上角,有点隐蔽:

python爬虫实战演示_第3张图片

模拟登陆大体上有两种,即添加cookie和使用post请求添加账号密码。由于后面的实战会涉及到前一种,所以这个实战就先用后一种了。

核心思路是,获取网站用以验证账号密码的url,然后把我们准备好的账号密码以post请求的形式发给它,这样就相当于登陆成功了。

怎么找目标url?

我们先手动登陆试试,点击登录后,注视着“检查”里的Network栏,你会发现一个“一闪即逝”的文件:

python爬虫实战演示_第4张图片

“小老弟,跑的挺快啊”

我们点击左上角的停止键,就可以获得这个文件,点开就有了url,顺便再抄一下user-agent

翻到下面,有一个“Form Data”,一看就是我们提交的账号密码:

python爬虫实战演示_第5张图片
不许盗号!!!

这个checkbox代表的是那个“下次自动登录”选项,on自然就是表示“勾选”

代码:

import requests

url = 'https://www.stoneread.com/login/logincheck?ur='
headers = {
     
    'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'
}
data = {
     
    'username' : '[email protected]',
    'password' : '12345ssdlh',
    'checkbox' : 'on'
}

resp = requests.post(url,headers=headers,data=data)
print(resp.content.decode('utf-8'))

结果中有“登陆成功”字样,和我们看到的页面一致。嘿嘿,成功啦~


设置代理ip

这个方法它成功几率不太大,因为我用的是免费的代理ip,没氪金怎么会变强呢它就不太稳定。我先把验证方法给一下。

获取免费ip的网址:

  • 快代理:https://www.kuaidaili.com/free/
  • 芝麻代理:http://http.zhimaruanjian.com/
  • 太阳代理:http://http.taiyangruanjian.com/
  • 讯代理:http://www.xdaili.cn/
  • 蚂蚁代理:http://www.mayidaili.com/
  • 极光代理:http://www.jiguangdaili.com/

查看当前ip的请求url:http://www.httpbin.org/ip

ps. http://www.httpbin.org/是一个功能很强大的网站,大家可以访问一下康康

我们先不用代理,看一下自己的ip地址

import requests
url = 'http://www.httpbin.org/ip'
resp = requests.get(url)
print(resp.text)

这个时候,就会打印出我自己电脑的真实ip

然后我们为它添加代理:

import requests
proxy = {
      # 免费的代理ip,这会儿估计已经没法用了
    'http':'111.77.197.127:9999'
}
url = 'http://www.httpbin.org/ip'
resp = requests.get(url,proxies=proxy)
print(resp.text)

这个时候如果你欧了一把,选的代理ip恰好是可以用的,那你就会看到程序打印出了你选的ip地址。

附:

  1. urllib库设置代理的方法——ProxyHandler处理器

    from urllib import request
    
    url = 'http://httpbin.org/ip'
    
    #1. 使用ProxyHandler,传入代理构建一个handler,代理的结构是字典
    handler = request.ProxyHandler({
           'http':'122.193.244.243:9999'})
    
    #2. 使用上面创建的handler构建一个opener
    opener = request.build_opener(handler)
    
    #3. 使用opener去发送一个请求
    resp = opener.open(url)
    print(resp.read())
    
  2. selenium设置代理的方法

    options = webdriver.ChromeOptions() # 创建ChromeOptions对象
    options.add_argument("--proxy-server=htto://175.43.151.209:9999") # 代理
    driver = webdriver.Chrome(executable_path="/Users/pangyuxuan/Desktop/chromedriver",chrome_options=options) # 在driver路径后添加代理参数
    driver.get("http://httpbin.org/ip")
    
  3. 在Scrapy中设置代理

    设置普通代理

    class IPProxyDownloadMiddleware(object):
    PROXIES = [
     "5.196.189.50:8080",
    ]
    def process_request(self,request,spider):
        proxy = random.choice(self.PROXIES)
        print('被选中的代理:%s' % proxy)
        request.meta['proxy'] = "http://" + proxy
    

    设置独享代理

    class IPProxyDownloadMiddleware(object):
    def process_request(self,request,spider):
        proxy = '121.199.6.124:16816'
        user_password = "970138074:rcdj35xx"
        request.meta['proxy'] = proxy
        # bytes
        b64_user_password = base64.b64encode(user_password.encode('utf-8'))
        request.headers['Proxy-Authorization'] = 'Basic ' + b64_user_password.decode('utf-8')
    

爬取瓜子二手车交易信息

网址:https://www.guazi.com/www/buy/

我们先什么都不加,直接请求网址,看输出是什么,再逐渐的添加请求头里的内容,来尝试网站究竟是用什么作为反爬虫的检测依据的。

什么都不加:

import requests
from lxml import etree
url = 'https://www.guazi.com/www/buy/'
resp = requests.get(url)
print(resp.text)

输出:

python爬虫实战演示_第6张图片

经过比较,它和网页源代码不一致,且最后还出现了乱码现象,说明text把解码方法猜错了——体现了content.decode('utf-8')的稳定性

添加User-agent:

import requests
from lxml import etree
url = 'https://www.guazi.com/www/buy/'
headers = {
     
    'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'
}
resp = requests.get(url,headers=headers)
print(resp.content.decode('utf-8'))

哈哈!还是不行。

添加cookie:

import requests
from lxml import etree
url = 'https://www.guazi.com/www/buy/'
headers = {
     
    'Cookie' : 'uuid=8375fbff-6a87-4130-8c96-7a4aa8d30728; ganji_uuid=8329982395237678242215; cainfo=%7B%22ca_a%22%3A%22-%22%2C%22ca_b%22%3A%22-%22%2C%22ca_s%22%3A%22self%22%2C%22ca_n%22%3A%22self%22%2C%22ca_medium%22%3A%22-%22%2C%22ca_term%22%3A%22-%22%2C%22ca_content%22%3A%22-%22%2C%22ca_campaign%22%3A%22-%22%2C%22ca_kw%22%3A%22-%22%2C%22ca_i%22%3A%22-%22%2C%22scode%22%3A%22-%22%2C%22keyword%22%3A%22-%22%2C%22ca_keywordid%22%3A%22-%22%2C%22display_finance_flag%22%3A%22-%22%2C%22platform%22%3A%221%22%2C%22version%22%3A1%2C%22client_ab%22%3A%22-%22%2C%22guid%22%3A%228375fbff-6a87-4130-8c96-7a4aa8d30728%22%2C%22ca_city%22%3A%22qd%22%2C%22sessionid%22%3A%22dbe4532a-24f9-45fc-8c5f-b9518a2efb46%22%7D; antipas=93901707482fmWd51E58673WzOJ; cityDomain=www; clueSourceCode=%2A%2300; user_city_id=-1; preTime=%7B%22last%22%3A1611505261%2C%22this%22%3A1610175479%2C%22pre%22%3A1610175479%7D; sessionid=30370a7d-e999-43e4-a614-4ffacc7c8e75; lg=1; Hm_lvt_bf3ee5b290ce731c7a4ce7a617256354=1610175480,1610175573,1610524515,1611505262; Hm_lpvt_bf3ee5b290ce731c7a4ce7a617256354=1611505262',
    'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'
}
resp = requests.get(url,headers=headers)
print(resp.content.decode('utf-8'))

哈哈!竟然行了!

虽然我自己试的时候还额外添加了Host,但不知道为什么现在只加一个cookie就行了。

后续的思路就是我们通过“检查”,在Elements里找到详情页的链接如图:

python爬虫实战演示_第7张图片

并且不同的车存放在不同的

  • 标签中:

    python爬虫实战演示_第8张图片

    所以我们遍历所有

  • 标签,依次访问每辆车的详情页面,再获取详情页面的车辆信息,进行存储即可。感兴趣的同学可以自行完成后面的代码,也可以找我要一下之前的代码

    爬取豆瓣top250

    网址:https://movie.douban.com/top250

    这个案例也是我学习时候,花比较多时间做的一个案例,虽然它没有什么很惊艳的实现技巧,但我在做的时候遇到了这样一个问题:

    python爬虫实战演示_第9张图片

    考虑到我囊中羞涩,没有租60r/月的代理服务器,而免费代理它又不太稳定,于是我选择老老实实的注册登陆。没错我就是前几天才注册豆瓣

    很简单,只要登录以后添加cookie信息就可以了。

    代码如下,做到存储数据之前:

    import requests
    from bs4 import BeautifulSoup
    
    headers = {
         
        'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
        'Cookie' : 'll="118221"; bid=Dp60PRKNGWI; __yadk_uid=t4cy7TbKsr834lpYtjbt0Vn6au2yF7oP; _vwo_uuid_v2=D181BE4292803A62776208FF476CE0C21|403fd897a559fbd412c3a7530efb5d2f; __gads=ID=546d1adef9db7e77-221ec2b1c5c5000a:T=1611226743:RT=1611226743:S=ALNI_MZmgV9oiEJeTVAfAnDiNlwsRm8WMQ; ap_v=0,6.0; __utmc=30149280; __utmz=30149280.1611299250.2.2.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmc=223695111; __utmz=223695111.1611299250.2.2.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1611302352%2C%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DStwtEMgge76IHS2f9aoITF2La9KliUfVdz-ShjuHwB78oJQFmijIAnaCAMgiQfxo%26wd%3D%26eqid%3Dd8a7eb3b0003fac200000002600a79b0%22%5D; _pk_ses.100001.4cf6=*; __utma=30149280.233705150.1611225868.1611299250.1611302352.3; __utma=223695111.583107523.1611225868.1611299250.1611302352.3; __utmb=223695111.0.10.1611302352; dbcl2="231087110:rCDcDbFTf0I"; ck=rEkU; push_noty_num=0; push_doumail_num=0; __utmt=1; __utmv=30149280.23108; __utmb=30149280.2.10.1611302352; _pk_id.100001.4cf6=fcbcfa39023ea437.1611225868.3.1611304162.1611299286.'
    }
    
    # 函数:获取详情页面的url,返回一个列表
    def get_detail_urls(url):
        resp = requests.get(url, headers=headers)
        # 获取详情页面url
        html = resp.text
        soup = BeautifulSoup(html, 'lxml')
        lis = soup.find('ol', class_='grid_view').find_all('li')
        # 经搜索,grid_view属性值唯一,故用find直接找到即可
        detail_urls = [] # 列表
        for li in lis:
            detail_url = li.find('a')['href']
            detail_urls.append(detail_url)
        return detail_urls
    
    
    def parse_detail_url(url):
        resp = requests.get(url,headers=headers)
        html = resp.text
        soup = BeautifulSoup(html,'lxml')
        lis = []
        name = list(soup.find('span',property='v:itemreviewed').stripped_strings)
        name = ''.join(name)
        lis.append(name)
        director = list(soup.find('div',id='info').find_all('span')[0].stripped_strings)
        director = ''.join(director)
        lis.append(director)
        actor = list(soup.find('div',id='info').find('span',class_='actor').stripped_strings)
        actor = ''.join(actor)
        lis.append(actor)
        score = soup.find('strong',class_='ll rating_num').string
        lis.append(score)
        remark = list(soup.find('span',property='v:summary').stripped_strings)
        remark = ''.join(remark)
        lis.append(remark)
        print(lis)
    
    
    def main():
        base_url = 'https://movie.douban.com/top250?start={}&filter='
        for x in range(0,251,25):
            url = base_url.format(x)
            detail_urls = get_detail_urls(url)
            for detail_url in detail_urls:
                parse_detail_url(detail_url)
            # resp = requests.get(detail_url,headers=headers)
            # html = resp.text
            # soup = BeautifulSoup(html,'lxml')
            # name = list(soup.find('div',id='content').find('h1').stripped_strings)
            # title = list(soup.find('span',property='v:itemreviewed').stripped_strings)
            # name = ''.join(name) # 将列表转化为字符串
            # director = list(soup.find('a',rel='v:directedBy'))
            # director = list(soup.find('div',id='info').find('span',class_='attrs').stripped_strings)
            # print(director)
            # writer = list(soup.find('div',id='info').find_all('span')[3].find('span',class_='attrs').stripped_strings)
            # writer = ''.join(writer)
            # print(writer)
            # actor = list(soup.find('div',id='info').find('span',class_='actor').stripped_strings)
            # actor = ''.join(actor)
            # print(actor)
            # remark = list(soup.find('span',class_='all hidden').stripped_strings)
            # print(remark)
            # score = list(soup.find('strong',class_='ll rating_num').stripped_strings)
            # print(score)
    
    
    if __name__ == '__main__':
        main()
    

    好家伙,我写这个文档时候,为了要上面那个“状态异常”的截图,把cookie删了以后疯狂爬取,直接导致我被封号了:

    python爬虫实战演示_第10张图片

    而且好像还没那么容易解锁。

    python爬虫实战演示_第11张图片

    哎,先看最后一个吧


    selenium行为链实战

    有些厉害的网站会根据鼠标行为判断你是人还是爬虫,这个时候selenium库的行为链就可以帮你的爬虫躲过检查。因为我还没遇到这么牛逼的网站,所以就随便举个例子,说一下行为链的语法了。

    比如我想在百度主页搜索“元尊”

    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains
    
    driver = webdriver.Chrome(executable_path="/Users/pangyuxuan/Desktop/chromedriver")
    driver.get("https://www.baidu.com/")
    
    inputTag = driver.find_element_by_id('kw') # 获取输入框
    submitTag = driver.find_element_by_id('su') # 获取按钮"百度一下"
    
    actions = ActionChains(driver) # 创建行为链对象actions
    
    actions.move_to_element(inputTag) # 鼠标移动到inputTag
    
    actions.send_keys_to_element(inputTag,'元尊') # 输入要搜索的内容
    
    actions.move_to_element(submitTag) # 鼠标移动到提交按钮
    
    actions.click(submitTag) # 点击提交
    
    actions.perform() # 上面的都是在定义,还没执行,通过perform执行
    
    

    还有更多的鼠标相关的操作。
    click_and_hold(element) :点击但不松开鼠标。
    context_click(element) :右键点击。
    double_click(element) :双击。

    更多方法请参考:http://selenium-python.readthedocs.io/api.html


    彩蛋:关于我被封号这件事
    python爬虫实战演示_第12张图片
    python爬虫实战演示_第13张图片

  • 你可能感兴趣的:(python,python,selenium,爬虫,requests)