精华内容
下载资源
问答
  • Python 爬虫 api

    2021-07-11 10:01:42
    刚开始学python爬虫, 前段时间见到通过api爬取信息的方法, 已经能够找到网页api 但是对于信息获取还是云里雾里 各位兄@弟姐妹们 有什么通俗易懂的书推荐下吗 (●°u°●)​ 
  • Python爬虫入门项目

    万次阅读 多人点赞 2017-12-25 16:26:21
    Python是什么 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言。 创始人Guido van Rossum是BBC出品英剧Monty Python’s Flying Circus(中文:蒙提·派森的...

    Python是什么

    Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言。

    创始人Guido van Rossum是BBC出品英剧Monty Python’s Flying Circus(中文:蒙提·派森的飞行马戏团)的狂热粉丝,因而将自己创造的这门编程语言命名为Python。

    人生苦短,我用python,翻译自"Life is short, you need Python"

    Python英式发音:/ˈpaɪθən/ ,中文类似‘拍森’。而美式发音:/ˈpaɪθɑːn/,中文类似‘拍赏’。我看麻省理工授课教授读的是‘拍赏’,我觉得国内大多是读‘拍森’吧。

    2017年python排第一也无可争议,比较AI第一语言,在当下人工智能大数据大火的情况下,python无愧第一语言的称号,至于C、C++、java都是万年的老大哥了,在代码量比较方面,小编相信java肯定是完爆其它语言的。

    不过从这一年的编程语言流行趋势看,java依然是传播最多的,比较无论app、web、云计算都离不开,而其相对python而言,学习路径更困难一点,想要转行编程,而且追赶潮流,python已然是最佳语言。

    许多大型网站就是用Python开发的,国内:豆瓣、搜狐、金山、腾讯、盛大、网易、百度、阿里、淘宝、热酷、土豆、新浪、果壳…; 国外:谷歌、NASA、YouTube、Facebook、工业光魔、红帽…

    Python将被纳入高考内容

    浙江省信息技术课程改革方案已经出台,Python确定进入浙江省信息技术高考,从2018年起浙江省信息技术教材编程语言将会从vb更换为Python。其实不止浙江,教育大省北京和山东也确定要把Python编程基础纳入信息技术课程和高考的内容体系,Python语言课程化也将成为孩子学习的一种趋势。尤其山东省最新出版的小学信息技术六年级教材也加入了Python内容,小学生都开始接触Python语言了!!

    再不学习,又要被小学生完爆了。。。

     

    Python入门教程

    Python能做什么

    • 网络爬虫
    • Web应用开发
    • 系统网络运维
    • 科学与数字计算
    • 图形界面开发
    • 网络编程
    • 自然语言处理(NLP)
    • 人工智能
    • 区块链
    • 多不胜举。。。

    Python入门爬虫

    这是我的第一个python项目,在这里与大家分享出来~

    • 需求
      • 我们目前正在开发一款产品其功能大致是:用户收到短信如:购买了电影票或者火车票机票之类的事件。然后app读取短信,解析短信,获取时间地点,然后后台自动建立一个备忘录,在事件开始前1小时提醒用户。
    • 设计
      • 开始我们将解析的功能放在了服务端,但是后来考虑到用户隐私问题。后来将解析功能放到了app端,服务端只负责收集数据,然后将新数据发送给app端。
      • 关于服务端主要是分离出两个功能,一、响应app端请求返回数据。二、爬取数据,存入数据库。
      • 响应请求返回数据使用java来做,而爬取数据存入数据库使用python来做,这样分别使用不同语言来做是因为这两种语言各有优势,java效率比python高些,适合做web端,而爬取数据并不是太追求性能且python语言和大量的库适合做爬虫。
    • 代码
      • 本项目使用python3的版本
      • 获取源码:扫描下方关注微信公众号「裸睡的猪」回复:爬虫入门 获取
         

         

      • 了解这个项目你只需要有简单的python基础,能了解python语法就可以。其实我自己也是python没学完,然后就开始写,遇到问题就百度,边做边学这样才不至于很枯燥,因为python可以做一些很有意思的事情,比如模拟连续登录挣积分,比如我最近在写一个预定模范出行车子的python脚本。推荐看廖雪峰的python入门教程
      • 首先带大家看看我的目录结构,开始我打算是定义一个非常好非常全的规范,后来才发现由于自己不熟悉框架,而是刚入门级别,所以就放弃了。从简而入:
      • 下面咱们按照上图中的顺序,从上往下一个一个文件的讲解init.py包的标识文件,python包就是文件夹,当改文件夹下有一个init.py文件后它就成为一个package,我在这个包中引入一些py供其他py调用。

    init.py

    # -*- coding: UTF-8 -*-  
    
    # import need manager module  
    import MongoUtil  
    import FileUtil  
    import conf_dev  
    import conf_test  
    import scratch_airport_name  
    import scratch_flight_number  
    import scratch_movie_name  
    import scratch_train_number  
    import scratch_train_station  
    import MainUtil
    

    下面两个是配置文件,第一个是开发环境的(windows),第二个是测试环境的(linux),然后再根据不同系统启用不同的配置文件

    conf_dev.py

    # -*- coding: UTF-8 -*-  
    # the configuration file of develop environment  
    
    # path configure  
    data_root_path = 'E:/APK98_GNBJ_SMARTSERVER/Proj-gionee-data/smart/data'  
    
    # mongodb configure  
    user = "cmc"  
    pwd = "123456"  
    server = "localhost"  
    port = "27017"  
    db_name = "smartdb"
    

    conf_test.py

    # -*- coding: UTF-8 -*-  
    # the configuration file of test environment  
    
    #path configure  
    data_root_path = '/data/app/smart/data'  
    
    #mongodb configure  
    user = "smart"  
    pwd = "123456"  
    server = "10.8.0.30"  
    port = "27017"  
    db_name = "smartdb"
    

    下面文件是一个util文件,主要是读取原文件的内容,还有将新内容写入原文件。

    FileUtil.py

    # -*- coding: UTF-8 -*-  
    import conf_dev  
    import conf_test  
    import platform  
    
    
    # configure Multi-confronment  
    # 判断当前系统,并引入相对的配置文件
    platform_os = platform.system()  
    config = conf_dev  
    if (platform_os == 'Linux'):  
        config = conf_test  
    # path  
    data_root_path = config.data_root_path  
    
    
    # load old data  
    def read(resources_file_path, encode='utf-8'):  
        file_path = data_root_path + resources_file_path  
        outputs = []  
        for line in open(file_path, encoding=encode):  
            if not line.startswith("//"):  
                outputs.append(line.strip('\n').split(',')[-1])  
        return outputs  
    
    
    # append new data to file from scratch  
    def append(resources_file_path, data, encode='utf-8'):  
        file_path = data_root_path + resources_file_path  
        with open(file_path, 'a', encoding=encode) as f:  
            f.write(data)  
        f.close
    

    下面这个main方法控制着执行流程,其他的执行方法调用这个main方法

    MainUtil.py

    # -*- coding: UTF-8 -*-  
    
    import sys  
    from datetime import datetime  
    import MongoUtil  
    import FileUtil  
    
    # @param resources_file_path 资源文件的path  
    # @param base_url 爬取的连接  
    # @param scratch_func 爬取的方法  
    def main(resources_file_path, base_url, scratch_func):  
        old_data = FileUtil.read(resources_file_path)   #读取原资源  
        new_data = scratch_func(base_url, old_data)     #爬取新资源  
        if new_data:        #如果新数据不为空  
            date_new_data = "//" + datetime.now().strftime('%Y-%m-%d') + "\n" + "\n".join(new_data) + "\n"      #在新数据前面加上当前日期  
            FileUtil.append(resources_file_path, date_new_data)     #将新数据追加到文件中  
            MongoUtil.insert(resources_file_path, date_new_data)    #将新数据插入到mongodb数据库中  
        else:   #如果新数据为空,则打印日志  
            print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), '----', getattr(scratch_func, '__name__'), ": nothing to update ")
    

    将更新的内容插入mongodb中

    MongoUtil.py

    # -*- coding: UTF-8 -*-  
    
    import platform  
    from pymongo import MongoClient  
    from datetime import datetime, timedelta, timezone  
    import conf_dev  
    import conf_test  
    
    # configure Multi-confronment  
    platform_os = platform.system()  
    config = conf_dev  
    if (platform_os == 'Linux'):  
        config = conf_test  
    # mongodb  
    uri = 'mongodb://' + config.user + ':' + config.pwd + '@' + config.server + ':' + config.port + '/' + config.db_name  
    
    
    # 将数据写入mongodb  
    # @author chenmc  
    # @param uri connect to mongodb  
    # @path save mongodb field  
    # @data save mongodb field  
    # @operation save mongodb field default value 'append'  
    # @date 2017/12/07 16:30  
    # 先在mongodb中插入一条自增数据 db.sequence.insert({ "_id" : "version","seq" : 1})  
    
    def insert(path, data, operation='append'):  
        client = MongoClient(uri)  
        resources = client.smartdb.resources  
        sequence = client.smartdb.sequence  
        seq = sequence.find_one({"_id": "version"})["seq"]      #获取自增id  
        sequence.update_one({"_id": "version"}, {"$inc": {"seq": 1}})       #自增id+1  
        post_data = {"_class": "com.gionee.smart.domain.entity.Resources", "version": seq, "path": path,  
                     "content": data, "status": "enable", "operation": operation,  
                     "createtime": datetime.now(timezone(timedelta(hours=8)))}  
        resources.insert(post_data)     #插入数据
    

    项目引入的第三方库,可使用pip install -r requirements.txt下载第三方库

    requirements.txt

    # need to install module# need to install module  
    bs4  
    pymongo  
    requests  
    json
    

    下面真正的执行方法来了,这五个py分别表示爬取五种信息:机场名、航班号、电影名、列车号、列车站。他们的结构都差不多,如下:

    第一部分:定义查找的url;
    第二部分:获取并与旧数据比较,返回新数据;
    第三部分:main方法,执行写入新数据到文件和mongodb中;
    

    scratch_airport_name.py:爬取全国机场

    # -*- coding: UTF-8 -*-  
    import requests  
    import bs4  
    import json  
    import MainUtil  
    
    resources_file_path = '/resources/airplane/airportNameList.ini'  
    scratch_url_old = 'https://data.variflight.com/profiles/profilesapi/search'  
    scratch_url = 'https://data.variflight.com/analytics/codeapi/initialList'  
    get_city_url = 'https://data.variflight.com/profiles/Airports/%s'  
    
    
    #传入查找网页的url和旧数据,然后本方法会比对原数据中是否有新的条目,如果有则不加入,如果没有则重新加入,最后返回新数据
    def scratch_airport_name(scratch_url, old_airports):  
        new_airports = []  
        data = requests.get(scratch_url).text  
        all_airport_json = json.loads(data)['data']  
        for airport_by_word in all_airport_json.values():  
            for airport in airport_by_word:  
                if airport['fn'] not in old_airports:  
                    get_city_uri = get_city_url % airport['id']  
                    data2 = requests.get(get_city_uri).text  
                    soup = bs4.BeautifulSoup(data2, "html.parser")  
                    city = soup.find('span', text="城市").next_sibling.text  
                    new_airports.append(city + ',' + airport['fn'])  
        return new_airports  
    
     #main方法,执行这个py,默认调用main方法,相当于java的main
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_airport_name)
    

    scratch_flight_number.py:爬取全国航班号

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    
    import requests  
    import bs4  
    import MainUtil  
    
    resources_file_path = '/resources/airplane/flightNameList.ini'  
    scratch_url = 'http://www.variflight.com/sitemap.html?AE71649A58c77='  
    
    
    def scratch_flight_number(scratch_url, old_flights):  
        new_flights = []  
        data = requests.get(scratch_url).text  
        soup = bs4.BeautifulSoup(data, "html.parser")  
        a_flights = soup.find('div', class_='list').find_all('a', recursive=False)  
        for flight in a_flights:  
            if flight.text not in old_flights and flight.text != '国内航段列表':  
                new_flights.append(flight.text)  
        return new_flights  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_flight_number)
    

    scratch_movie_name.py:爬取最近上映的电影

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    import re  
    import requests  
    import bs4  
    import json  
    import MainUtil  
    
    # 相对路径,也是需要将此路径存入数据库  
    resources_file_path = '/resources/movie/cinemaNameList.ini'  
    scratch_url = 'http://theater.mtime.com/China_Beijing/'  
    
    
    # scratch data with define url  
    def scratch_latest_movies(scratch_url, old_movies):  
        data = requests.get(scratch_url).text  
        soup = bs4.BeautifulSoup(data, "html.parser")  
        new_movies = []  
        new_movies_json = json.loads(  
            soup.find('script', text=re.compile("var hotplaySvList")).text.split("=")[1].replace(";", ""))  
        coming_movies_data = soup.find_all('li', class_='i_wantmovie')  
        # 上映的电影  
        for movie in new_movies_json:  
            move_name = movie['Title']  
            if move_name not in old_movies:  
                new_movies.append(movie['Title'])  
        # 即将上映的电影  
        for coming_movie in coming_movies_data:  
            coming_movie_name = coming_movie.h3.a.text  
            if coming_movie_name not in old_movies and coming_movie_name not in new_movies:  
                new_movies.append(coming_movie_name)  
        return new_movies  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_latest_movies)
    

    scratch_train_number.py:爬取全国列车号

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    import requests  
    import bs4  
    import json  
    import MainUtil  
    
    resources_file_path = '/resources/train/trainNameList.ini'  
    scratch_url = 'http://www.59178.com/checi/'  
    
    
    def scratch_train_number(scratch_url, old_trains):  
        new_trains = []  
        resp = requests.get(scratch_url)  
        data = resp.text.encode(resp.encoding).decode('gb2312')  
        soup = bs4.BeautifulSoup(data, "html.parser")  
        a_trains = soup.find('table').find_all('a')  
        for train in a_trains:  
            if train.text not in old_trains and train.text:  
                new_trains.append(train.text)  
        return new_trains  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_train_number)
    

    scratch_train_station.py:爬取全国列车站

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    import requests  
    import bs4  
    import random  
    import MainUtil  
    
    resources_file_path = '/resources/train/trainStationNameList.ini'  
    scratch_url = 'http://www.smskb.com/train/'  
    
    
    def scratch_train_station(scratch_url, old_stations):  
        new_stations = []  
        provinces_eng = (  
            "Anhui", "Beijing", "Chongqing", "Fujian", "Gansu", "Guangdong", "Guangxi", "Guizhou", "Hainan", "Hebei",  
            "Heilongjiang", "Henan", "Hubei", "Hunan", "Jiangsu", "Jiangxi", "Jilin", "Liaoning", "Ningxia", "Qinghai",  
            "Shandong", "Shanghai", "Shanxi", "Shanxisheng", "Sichuan", "Tianjin", "Neimenggu", "Xianggang", "Xinjiang",  
            "Xizang",  
            "Yunnan", "Zhejiang")  
        provinces_chi = (  
            "安徽", "北京", "重庆", "福建", "甘肃", "广东", "广西", "贵州", "海南", "河北",  
            "黑龙江", "河南", "湖北", "湖南", "江苏", "江西", "吉林", "辽宁", "宁夏", "青海",  
            "山东", "上海", "陕西", "山西", "四川", "天津", "内蒙古", "香港", "新疆", "西藏",  
            "云南", "浙江")  
        for i in range(0, provinces_eng.__len__(), 1):  
            cur_url = scratch_url + provinces_eng[i] + ".htm"  
            resp = requests.get(cur_url)  
            data = resp.text.encode(resp.encoding).decode('gbk')  
            soup = bs4.BeautifulSoup(data, "html.parser")  
            a_stations = soup.find('left').find('table').find_all('a')  
            for station in a_stations:  
                if station.text not in old_stations:  
                    new_stations.append(provinces_chi[i] + ',' + station.text)  
        return new_stations  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_train_station)
    

    将项目放到测试服务器(centos7系统)中运行起来,我写了一个crontab,定时调用他们,下面贴出crontab。

    /etc/crontab

    SHELL=/bin/bash  
    PATH=/sbin:/bin:/usr/sbin:/usr/bin  
    MAILTO=root  
    
    # For details see man 4 crontabs  
    
    # Example of job definition:  
    # .---------------- minute (0 - 59)  
    # |  .------------- hour (0 - 23)  
    # |  |  .---------- day of month (1 - 31)  
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...  
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat  
    # |  |  |  |  |  
    # *  *  *  *  * user-name  command to be executed  
      0  0  *  *  * root python3 /data/app/smart/py/scratch_movie_name.py    >> /data/logs/smartpy/out.log 2>&1  
      0  1  *  *  1 root python3 /data/app/smart/py/scratch_train_station.py >> /data/logs/smartpy/out.log 2>&1  
      0  2  *  *  2 root python3 /data/app/smart/py/scratch_train_number.py  >> /data/logs/smartpy/out.log 2>&1  
      0  3  *  *  4 root python3 /data/app/smart/py/scratch_flight_number.py >> /data/logs/smartpy/out.log 2>&1  
      0  4  *  *  5 root python3 /data/app/smart/py/scratch_airport_name.py  >> /data/logs/smartpy/out.log 2>&1
    

    后续

    目前项目已经正常运行了三个多月啦。。。

    有问题反馈

    在阅读与学习中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流

    • 微信公众号:裸睡的猪
    • 在下面留言
    • 直接给我私信

    关于此公众号

    • 后期或提供各种软件的免费激活码
    • 推送python,java等编程技术文章和面试技巧
    • 当然你们可以将你们感兴趣的东西直接送给我
    • 谢谢你们真诚的关注,此公众号以后获得的收益将全部通过抽奖的形式送给大家
    • 以后如果博主要创业的话,也会在此公众号中挑选小伙伴哦~
    • 希望大家分享出去,让更多想学习python的朋友看到~

     

     

    展开全文
  • python爬虫获取天猫店铺信息 爬取需求 在天猫搜索一个关键词,然后抓取这个关键词下的相关店铺,由于taobao的反爬策略,只能爬取到第十页大概200个店铺的信息。 效果预览 最终爬取的数据用excel保存,部分数据如下 ...

    python爬虫获取天猫店铺信息

    爬取需求

    在天猫搜索一个关键词,然后抓取这个关键词下的相关店铺,由于taobao的反爬策略,只能爬取到第十页大概200个店铺的信息。

    效果预览

    最终爬取的数据用excel保存,部分数据如下

    在这里插入图片描述

    环境准备

    代码

    # coding=utf-8
    # @Time : 2020/6/11 19:51 
    # @Author : mxz
    # @File : main.py 
    # @Software: PyCharm
    
    
    import re
    import time
    import pandas as pd
    from selenium import webdriver
    from selenium.webdriver import ActionChains
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    
    from bs4 import BeautifulSoup
    
    
    from fateadm_api import FateadmApi
    
    PRED_TYPE= "30500"
    
    
    class TmallShopSpider(object):
        def __init__(self, username, password, chromedriver_path):
            self.url = 'https://login.taobao.com/member/login.jhtml'  # 淘宝登录地址
            self.username = username  # 接收传入的 账号
            self.password = password  # 接收传入的 密码
            options = webdriver.ChromeOptions()
            options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})  # 不加载图片,加快访问速度
            options.add_experimental_option('excludeSwitches', ['enable-automation'])  # 设置为开发者模式,防止被各大网站识别出来使用了Selenium
            self.browser = webdriver.Chrome(executable_path=chromedriver_path, chrome_options=options)  # 接收传入的 chromedriver地址 和设置好的 options
            self.browser.maximize_window()  # 设置窗口最大化
            self.wait = WebDriverWait(self.browser, 10)  # 设置一个智能等待为10秒
    
        def login(self,on_login_web):
            if not on_login_web:
                self.browser.get(self.url)
            # username_password_button = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.login-box.no-longlogin.module-quick > .hd > .login-switch')))  # 用css选择器选择 用账号密码登录按钮
            # username_password_button.click()  # 点击 用账号密码登录按钮
            weibo_button = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.weibo-login')))  # 用css选择器选择 用微博登录按钮
            weibo_button.click()  # 点击 用微博登录按钮
            input_username = self.wait.until(EC.presence_of_element_located((By.XPATH, '//input[@name="username"]')))  # 用xpath选择器选择 账号框
            input_username.send_keys(self.username)  # 输入 账号
            input_password = self.wait.until(EC.presence_of_element_located((By.XPATH, '//input[@name="password"]')))  # 用xpath选择器选择 密码框
            input_password.send_keys(self.password)  # 输入 密码
            time.sleep(3)
            login_button = self.wait.until(EC.presence_of_element_located((By.XPATH, '//span[text()="登录"]')))  # 用xpath选择器选择 登录按钮
            login_button.click()  # 点击 登录按钮
    
    
        def getPageTotal(self):
            # 存在登录后进入滑动验证码页面的情况,此时无法获取页数,做法是回退一步再次登录
            try:
                page_total = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.ui-page-skip > form')))  # 用css选择器选择 商品列表页 总页数框
                page_total = page_total.text
                page_total = re.match('.*?(\d+).*', page_total).group(1)  # 清洗
                return page_total
            except:
                if self.sliderVerification():
                    # self.browser.back()
                    self.login(on_login_web=True)
                    return self.getPageTotal()
    
    
        def dropDown(self):
            # 模拟人类 向下滑动浏览(下拉有加速度)
            for i in range(1, 52):
                drop_down = "var q=document.documentElement.scrollTop=" + str(i*100)
                self.browser.execute_script(drop_down)
                time.sleep(0.01)
                if i == 5:
                    time.sleep(0.7)
                if i == 15:
                    time.sleep(0.5)
                if i == 29:
                    time.sleep(0.3)
                if i == 44:
                    time.sleep(0.1)
            # 直接下拉到最底部
            # drop_down = "var q=document.documentElement.scrollTop=10000"
            # self.browser.execute_script(drop_down)
    
        def nextPage(self):
            # 获取 下一页的按钮 并 点击
            next_page_submit = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.ui-page-next')))
            next_page_submit.click()
    
        def sliderVerification(self):
            # 滑块验证有滑动,但验证失败,失败后人工滑动验证也会失败
    
            # 每次翻页后 检测是否有 滑块验证
            try:
                slider_button = WebDriverWait(self.browser, 5, 0.5).until(EC.presence_of_element_located((By.ID, 'nc_1_n1z')))
                # action = ActionChains(self.browser)
                # action.click_and_hold(slider_button).perform()
                # action.reset_actions()
                # # 模拟人类 向左拖动滑块(拖动有加速度)
                # for i in range(100):
                #     action.move_by_offset(i*1, 0).perform()
                #     time.sleep(0.01)
                # action.reset_actions()
    
                # 尝试出现验证码后返回上一页
                self.browser.back()
                return True
            except:
                print('没有检测到滑块验证码')
                return False
    
        def crawlShops(self, category):
            # self.login(on_login_web=False)
            self.browser.get('https://list.tmall.com/search_product.htm?q={0}'.format(category))  # 天猫商品列表页地址,format()里面输入要爬取的类目
            shop_button=self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.fType-w ')))
            shop_button.click()
            self.login(on_login_web=True)
            page_total = self.getPageTotal()  # 获取 商品列表页 总页数
            print(''.join(['爬取的类目一共有:', page_total, '页']))
            shop_data=[]
            for page in range(2, int(page_total)):  # 遍历 全部 商品列表页
                page_frame = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.ui-page-skipTo')))  # 获取 当前页数框
                page_now = page_frame.get_attribute('value')  # 获取 当前页数
                print(''.join(['当前页数:', page_now, ' ', '总页数:', page_total]))
                html = self.browser.page_source  # 获取 当前页面的 源代码
                soup=BeautifulSoup(html,'lxml')
                shop_list=soup.find_all(class_="shopHeader-info")
                for shop in shop_list:
                    one_data={}
                    one_data['种类']=category
                    one_data["店名"]=shop.find(class_="sHi-title").text
                    one_data["链接"]="https://list.tmall.com/"+shop.find(class_="sHi-title")['href']
                    one_data["页数"]=page_now
                    shop_data.append(one_data)
                    pd.DataFrame(shop_data).to_excel(category+".xlsx")
    
                self.dropDown()  # 执行 下拉动作
                self.nextPage()  # 执行 按下一页按钮动作
                time.sleep(1)
                self.sliderVerification()  # 检测是否有 滑块验证
                time.sleep(1)
                self.checkNotFoundWebPage()
                time.sleep(1)
            pd.DataFrame(shop_data).to_excel(category+".xlsx")
    
        def checkNotFoundWebPage(self):
            # 翻页时有时会出现无法找到相关店铺的页面,但其实还不是最后一页店铺,
            # 此时按返回上一步再次进入下一页
            try:
                search_tip = WebDriverWait(self.browser, 5, 0.5).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.searchTip-kw')))
    
                # 尝试出现验证码后返回上一页
                self.browser.back()
                return True
            except:
                print('没有检测到无法搜索店铺的页面')
                return False
    
    
    username = ''  # 你的 微博账号
    password = ''  # 你的 微博密码
    chromedriver_path = 'chromedriver.exe'  # 你的 selenium驱动 存放地址
    category = "职业装"  # 你要爬取的 搜索关键词
    
    if __name__ == '__main__':
        a = TmallShopSpider(username, password, chromedriver_path)
        a.crawlShops(category)
    

    难点

    代码里面已经有注释,一些难点与未解决的点列举如下

    1. sliderVerification用于处理出现滑动验证码的情况,在翻页查找靠后的店铺时(大概在第十页开始频繁出现),注释里面有模拟人工滑动验证的做法,但滑动后验证不成功,甚至在程序终止后人工去滑动也会一直失败,所以我选择了后退一步,回到上个页面然后继续点下一页。经过验证,这会导致上一页数据被重新爬取,我选择了最后在excel里删除重复项,读者可以选择在代码里去重,下面是滑动验证的界面
      在这里插入图片描述

    2. 有时候还会遇到出现无法搜到相关店铺的页面,如下图

    在这里插入图片描述
    但其实是能搜到的,做法跟上面一样,返回上一个页面,继续点下一页,同样也会造成数据重复,好处就是程序不容易终止,多试几次就又能找到店铺了,这应该也是taobao的一个反爬策略

    总结

    如果需要爬取的店铺数量不多的话上述代码可以解决,如果需要高一个数量级的店铺就需要想办法破解那个滑动验证码,如果已经有好的办法的话希望能一起讨论。

    展开全文
  • Python爬虫获取新冠肺炎数据

    千次阅读 2021-02-22 20:07:30
    本文描述了最基本的爬虫使用方法。 目标网站:https://news.qq.com/zt2020/page/feiyan.htm#/global 获取网站中外国某国家疫情感染人数。 一.网站分析 按F12进入开发者模式,查看目标网站的信息,以google浏览器为...

    本文描述了最基本的爬虫使用方法。
    目标网站:https://news.qq.com/zt2020/page/feiyan.htm#/global
    获取网站中外国某国家疫情感染人数。

    一.网站分析

    按F12进入开发者模式,查看目标网站的信息,以google浏览器为例子:
    在这里插入图片描述选择network中的XHR,可以看到name中有很多项,在网页中点开目标国家(俄罗斯)的具体信息,可以看到在name栏中最下方出现了一个新的信息,查看具体信息可以看到一些相关的信息。
    在这里插入图片描述http请求为post,参数为country,URL也可以查看。
    url最后类似于乱码形式的字符串为国家名转码以后的文本。如果需要获取其他国家的数据,只需要将url变为
    https://api.inews.qq.com/newsqa/v1/query/pubished/daily/list?country=国家名称&,
    在拼接时无法使用中文,可以使用quote方法进行转码。

    from urllib import parse # urllib为Python中用于处理http请求,parse子模块用于处理url
    
    URL = "https://api.inews.qq.com/newsqa/v1/query/pubished/daily/list?country=%s&"#基本格式
    
    country = input("请输入查询国家:")
    
    print(URL%(parse.quote(country)))# 使用unquote方法解析url
    

    输入目标国家后即可进行转码:
    在这里插入图片描述

    二.数据获取

    requests模块是Python中的http请求库,需要进行安装。
    浏览器在发送请求时会携带一些信息,为了达到模拟浏览器的目的,爬虫也需要加入这些信息进行伪装,可以直接将浏览器中对应信息直接粘贴过来。
    在这里插入图片描述在这里插入代码片

    request的使用格式:

    requests.post(url,[data,] [headers,] [proxies,] *args)
    

    -url:服务器对应的地址。
    -data:请求时携带的数据。
    -headers:HTTP请求中headers字段。
    -proxies:设置代理IP地址

    获取数据的程序如下:

    from urllib import parse # urllib为Python中用于处理http请求,parse子模块用于处理url
    import requests
    
    def get_response(country):
        URL = "https://api.inews.qq.com/newsqa/v1/automation/foreign/daily/list?country=%s&"#基本格式
        headers = {
        "Referer":"https://news.qq.com/",
        "Host":"api.inews.qq.com",
        "Origin":"https://news.qq.com",
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
        }
        url = URL%(parse.quote(country))
        data = {
        "country": country,
        }
        response = requests.post(url,data=data,headers=headers)
        print(url)
        return response
    
    # 查看获取的内容
    country = input("请输入查询国家:")
    res = get_response(country)
    print(res.text) # resposne.text 查看响应中的文本信息
    

    三.处理保存数据

    数据本身并不直观,需要进行处理。数据时字符串形式的字典(json), 将其转化为字典,然后使用pandas进行处理,最后保存至Excel文件中。
    最后的完整代码如下:

    from urllib import parse # urllib为Python中用于处理http请求,parse子模块用于处理url
    import requests
    
    def get_response(country):
        URL = "https://api.inews.qq.com/newsqa/v1/automation/foreign/daily/list?country=%s&"#基本格式
        headers = {
        "Referer":"https://news.qq.com/",
        "Host":"api.inews.qq.com",
        "Origin":"https://news.qq.com",
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
        }
        url = URL%(parse.quote(country))
        data = {
        "country": country,
        }
        response = requests.post(url,data=data,headers=headers)
        print(url)
        return response
    
    # 查看获取的内容
    country = input("请输入查询国家:")
    res = get_response(country)
    #print(res.text) # resposne.text 查看响应中的文本信息
    with open("yiqing.txt","a") as f:
        f.write(res.text)
    data = res.text
    data = eval(data) # 转为字典
    # 数据中只有data对应的键值对为数据
    data = data["data"]
    # 导入pandas ,需要进行安装
    import pandas as pd # 使用as给包起别名
    df = pd.DataFrame(data) # DataFrame为pandas中的一个数据结构,类似于二维表格
    df.to_excel("yiqing.xls", index=False) # to_csv可以写入到csv文件中
    df = pd.read_excel("yiqing.xls", index_col=None)
    df
    

    运行演示:
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 下面小编就为大家分享一篇Python爬虫实例_利用百度地图API批量获取城市所有的POI点,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 有一段时间没写关于爬虫的博客了,距离上一次自学爬虫已经过去了有一年的时间。想起刚写博客那会,没有什么粉丝,写关于大数据技术的博客受众面不是很广,所以基本上不怎么涨粉。每次涨粉都是因为那段时间分享的几篇...

            有一段时间没写关于爬虫的博客了,距离上一次自学爬虫已经过去了有一年的时间。想起刚写博客那会,没有什么粉丝,写关于大数据技术的博客受众面不是很广,所以基本上不怎么涨粉。每次涨粉都是因为那段时间分享的几篇关于爬虫入门的几个小Demo,像图片下载器,酷狗Top250,稍微难一点的像爬取拉勾网等等,至今历历在目…
    在这里插入图片描述
            虽然不是python专业的学子,但凭着对爬虫莫名的热爱,让我逐渐找回了曾经的自己。

    在这里插入图片描述
            本篇博客博主为大家带来关于使用Python爬虫获取猫眼电影Top100的信息和…作为一名图片党,所必不可少的每部电影的封面图😎

    在这里插入图片描述


    详细操作

            我们首先根据网址https://maoyan.com/board/4进入到猫眼的Top100榜单首页
    在这里插入图片描述
    注意:光理论是不够的,在此送大家一套2020最新Python全栈实战视频教程, 点击此处免费获取一起进步哦!

            通过观察其他页网址url的一个变化关系,我们可以尝试发现网址的变化规律

            第二页的网址https://maoyan.com/board/4?offset=10

            第三页的网址https://maoyan.com/board/4?offset=20

            …

            一直到最后一页的网址https://maoyan.com/board/4?offset=90

            我们可以写一个url的列表推导式

        urls = ['https://maoyan.com/board/4?offset={}'.format(i * 10)
        for i in range(10)]
    

            但这次咱用多线程的方式,先写好主程序入口,在main函数的调用中传递一个列表参数。

    
    if __name__ == '__main__':
        # 对每一页信息进行爬取
        pool = Pool()
        pool.map(main, [i * 10 for i in range(10)])
        pool.close()
        pool.join()
    

            猫眼电影网站有反爬虫措施,我们可以通过设置headers,“伪装”成浏览器进行爬取

    # 猫眼电影网站有反爬虫措施,设置headers后可以爬取
    headers = {
        'Content-Type': 'text/plain; charset=UTF-8',
        'Origin': 'https://maoyan.com',
        'Referer': 'https://maoyan.com/board/4',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
    }
    

            有了请求头和构造出来的url,我们就可以写个方法进行网页源码的捕捉。

    # 爬取网页源代码
    def get_one_page(url, headers):
        try:
            response = requests.get(url, headers=headers)
            if response.status_code == 200:
                return response.text
            return None
        except RequestException:
            return None
    

            有了源码,我们就可以对其进行解析。

            通过观察源代码,发现用正则表达式可以轻易获取到我们想要的信息。
    在这里插入图片描述
            于是可以用正则表达式进行信息的提取,将其返回的数据存放至一个字典里

    # 正则表达式提取信息
    def parse_one_page(html):
        pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
                             + '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',
                             re.S)
        items = re.findall(pattern, html)
        for item in items:
            yield {
                'index': item[0],
                'image': item[1],
                'title': item[2],
                'actor': item[3].strip()[3:],
                'time': item[4].strip()[5:],
                'score': item[5] + item[6]
            }
    

            现在有了内容,我们就应该考虑存储的问题了。

            为了方便查看,我们这里将其写入本地的txt文本。

    # 猫眼TOP100所有信息写入文件
    def write_to_file(content):
        # encoding ='utf-8',ensure_ascii =False,使写入文件的代码显示为中文
        with open('result.txt', 'a', encoding='utf-8') as f:
            f.write(json.dumps(content, ensure_ascii=False) + '\n')
            f.close()
    
    

    提示:
            这里使用dumps是将dict转化成str格式。另外json.dumps 序列化时对中文默认使用的ascii编码。因此想输出真正的中文需要指定ensure_ascii=False

            以为到这里就完了,是不是还忘了点啥😜

            对啊,我们还要下载每部电影对应的图片,但现在都已经获取到了每部电影的信息,下载图片那还不是轻轻松松。

            我们拿到图片的url,进行request访问,然后将返回的内容写入到本地目录下就ok了

    # 下载电影封面
    def save_image_file(url, path):
        jd = requests.get(url)
        if jd.status_code == 200:
            with open(path, 'wb') as f:
                f.write(jd.content)
                f.close()
    

            最后我们再完善一下我们的main函数。对上述所写的功能方法进行调用,并在本地创建文件夹covers用来存储结果数据。

    def main(offset):
        url = "https://maoyan.com/board/4?offset=" + str(offset)
        html = get_one_page(url, headers)
        if not os.path.exists('covers'):
            os.mkdir('covers')
        for item in parse_one_page(html):
            print(item)
            write_to_file(item)
            save_image_file(item['image'], 'covers/' + item['title'] + '.jpg')
    

            然后就可以运行程序了,可以看到用了多线程之后,速度快了很多。
    在这里插入图片描述
            待到程序运行完毕,我们打开同级目录下生成的result.txt文件
    在这里插入图片描述
            打开由程序创建的covers目录
    在这里插入图片描述
            我们任意点开一张图片,例如菌哥很喜欢的千与千寻
    在这里插入图片描述
    注意:最后送大家一套2020最新企业Pyhon项目实战视频教程,点击此处免费获取,希望大家一起进步哦!


            ok啦,看到类似上述的效果图,说明我们就成功啦~

            受益或对爬虫感兴趣的朋友记得点个赞支持一下~

            想要具体爬虫源码的朋友,可以扫码关注公众号【猿人菌】,后台回复"猫眼源码"即可获取

    扫码关注

    在这里插入图片描述

    关注即可获取高质量思维导图,互联网一线大厂面经,大数据珍藏精品书籍...期待您的关注!
    展开全文
  • 帮粉丝写Python爬虫之【获取CSDN周榜所有大佬的收费专栏】,做爬虫最终要的是什么?要到数据接口!
  • 写在前面:酒店和旅游景点方式不同,不能用我的写法,如果获取酒店数据请参考:https://blog.csdn.net/qq_34774456/article/details/89885296 旅游景点代码(地址要用手机版的携程搜自己想搜的景点): import ...
  • 在上一篇文章 https://blog.csdn.net/xHibiki/article/details/84134554 中,我们介绍了Mongo数据库以及管理工具Studio3T和adminMongo的下载安装,这次,我们结合Python爬虫和第三方模块Pymongo,爬取政府网站:深圳市...
  • 希望通过Python爬虫获取企业基本信息。目前已基本实现了这一需求。本文最后会提供具体的代码。代码仅供学习参考,希望不要恶意爬取数据! 二、分析 以苏宁为例。输入“江苏苏宁”后,查询结果如下: 经过分析,...
  • 通过小区名称利用百度api可以获取小区的地址以及经纬度,但是由于api返回的值中的地址形式不同,所以可以首先利用小区名称进行一轮爬虫获取小区的经纬度,然后再利用经纬度Reverse到小区的结构化的地址。...
  • Python爬虫实现获取斗鱼主播信息

    千次阅读 2018-05-19 11:44:28
    Python爬虫获取斗鱼主播信息
  • 文章目录requestsrequests基础requests模块发送get请求response响应对象response.text 和response.content的区别解决中文乱码response响应对象的其它常用属性或方法requests...标签的链接在文档中获取所有的文字内容
  • Python爬虫入门教程 99-100 Python爬虫在线服务大全

    万次阅读 多人点赞 2020-10-27 20:38:13
    python爬虫不能一味的蛮干,有时候借助第三方提供的工具或者服务,快速达成爬取目标,不失为一种奇妙的解决技巧。
  • Python 爬虫获取网易云音乐歌手歌词

    千次阅读 2018-08-09 16:54:15
    此文首发于公众号「brucepk」,欢迎直接去公众号看   “ 阅读文本大概需要 3.1 分钟 上一篇文章爬取了歌手的姓名和歌手的 id ,这篇文章根据...上篇文章没学会的也不要紧,公众号回复「歌手」可以获取上次的...
  • 主要用到python的requests库和BeatifulSoup库,代码如下: #encoding:utf-8 import requests import psycopg2 import datetime import re from bs4 import BeautifulSoup from apscheduler.schedulers.background ...
  • 目的:利用Python爬虫—利用百度地图API批量获取城市的POI点 经过一定阶段的学习,知道怎么在百度开放控制平台里获取有效地AK值,并且在网页里成功获取了POI的数据,根据得到的数据可以看出都是以json或xml格式的...
  • Python网络爬虫案例:百度地图API 使用百度API获取数据的实践案例,涉及的技术包括: 爬取网页:使用Requests请求百度地图API地址 解析网页:提取json数据 存储数据:存储至MySQL数据库 1.项目描述 通过百度...
  • 我的第一个Python爬虫——谈心得

    万次阅读 多人点赞 2018-03-30 19:24:26
    相信各大高校应该都有本校APP或超级课程表之类的软件,在信息化的时代能快速收集/查询自己想要的咨询也是种很重要的能力,所以记下了这篇博客,用于总结我所学到的东西,以及用于记录我的第一个爬虫的初生。...
  • 一、需求 每天需要从友盟网站获取...1)获取api秘钥 #获取api秘钥 def authorize(user, pasw): url = 'http://api.umeng.com/authorize' body = {'email': '%s'%(user), 'password': '%s'%(pasw)} response = req...
  • 原计划继续写一下关于手机APP的爬虫,结果发现夜神模拟器总是卡死,比较懒,不想找原因了,哈哈,所以接着写后面的博客了,从50篇开始要写几篇python爬虫的骚操作,也就是用Python3通过爬虫实现一些小工具。...
  • 环境: python3 直接上代码: Cookie、User-Agent 填自己的 1.BaiDuTranslateWeb.py import requests import execjs import json class BaiDuTranslateWeb: def __init__(self): self.url = "...
  • 对于Python爬虫爱好者来说,寻找美丽的姑娘是最喜欢做的事情之一了
  • 前言:本文主要涉及知识点包括新浪微博爬虫python对数据库的简单读写、简单的列表数据去重、简单的自然语言处理(snowNLP模块、机器学习)。适合有一定编程基础,并对python有所了解的盆友阅读。
  • python 爬虫之selenium可视化爬虫

    万次阅读 多人点赞 2020-08-05 19:52:11
    一文带你了解Python爬虫(一)——基本原理介绍 一文带你了解Python爬虫(二)——四种常见基础爬虫方法介绍 之所以把selenium爬虫称之为可视化爬虫 主要是相较于前面所提到的几种网页解析的爬虫方式 selenium爬虫...
  • Python爬虫:逆向分析某云音乐加密参数

    万次阅读 多人点赞 2020-09-05 09:54:07
    本篇博文通过对网易云音乐进行逆向分析,用Python代码模拟了AES和RSA加密过程,并在文章的末尾提供了一些参数,可以用这些参数来获取歌曲对应的歌词及用户的评论。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,378
精华内容 8,951
关键字:

python爬虫获取api

python 订阅
爬虫 订阅