Python爬虫案例应用

基本的语言特性的总结

因为要分析一个问题,手头上没有数据,在相关网站上找到后,发现要一个一个的点,正好使用Python来爬取并解析数据,获得相应的数据。
在互联网时代,个人获得公开的数据,并做一些分析和验证是值得肯定的。
考虑到业务分析以及技术实现角度,本次主要是涉及数据的爬取,后续的数据预处理以及分析,本文未做介绍。

代码示例

# !/usr/bin/python
# -*- coding:utf-8  -*-
# python3.7

""" 爬取网站和解析数据和存储数据"""
import requests
from bs4 import BeautifulSoup
import time
import pandas as pd


def joinURL(urlBase,urlNew,keepflag=False):
    """拼接url"""
    daw= urlBase.split('/')  #  /2019/index.html
    laststring = daw[-1].split('.')
    baselist = daw[0:len(daw)-1]
    if keepflag == False:
        resulturl =  "/".join(baselist)+'/'+urlNew  # /2019/happy.html
    else:
        resulturl =  "/".join(baselist) + '/' +laststring[0] +'/'+ urlNew # /2019/index/happy.html
    return(resulturl)

def getHtml(url,timeout=20, encodingtype='utf-8'):
    """爬取网址 """
    try:
        headers = {
    'Accept-Language': 'zh-cn',
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'Chrome/22.0.1207.1',
    }
        # 返回respond 对象
        respdata = requests.get(url, headers=headers, timeout=timeout)
        # 根据文本的编码格式设置文本的形式
        print(respdata.encoding)
        respdata.encoding = encodingtype
        html = respdata.text
        respdata.close()
 # 返回
        return html
    except Exception:
        print("NO connect")
        print(respdata.status_code)
        return None

def parseURLData(rawurl,levelkey,levefather):
    """解析HTML中的数据,并和之前的数据存储在一起,rawurl是原始的URL
       返回解析的数据urlLinkData 以及下一层的URL-DataUrl2
    """
    # 设定数据结构用来存储数据
    findata_list = []
    # 程序将在这里暂时三秒,爬虫不要给网站造成负担
    time.sleep(0.2)
    content = nationStatis.getHtml(rawurl,timeout=80,encodingtype='GBK')
    soup = BeautifulSoup(content, "html.parser")
    urlstart = soup.findAll("tr", {"class":levelkey})
    print("#######是否有标签,标签是否有所需要的属性 urlstart.attrs")
    for dataname in urlstart:
        # ataname.get_text将html所有标签都清除,返回一个只包含文字的字符串
        # 通过参数指定tag的文本内容的分隔符
        for mytag in  dataname.find_all(True):
            print(mytag.name)
            if mytag.name=='a':
                urlLinkLevel = mytag.get("href")
                if urlLinkLevel is not None:
                    DataUrl2 = joinURL(rawurl, urlLinkLevel, keepflag=False)
                else:
                    DataUrl2=''
            else:
                DataUrl2 = ''
        urlLinkData = dataname.get_text(',')
         # 不确定某个属性是否存在时,用 tag.get('attr') 方法去获取,没有会返回None
            tmp = (levefather,urlLinkData,DataUrl2)
            print(tmp)
        findata_list.append(tmp)
    return findata_list

def text_save(filename, data):
    """写入数据,filename为写入CSV文件的路径,data为要写入数据列表"""
    with open(filename, mode='w', encoding='utf-8') as fileobj:
        for i in range(len(data)):
            s = str(data[i]).replace('(','').replace(')','')#去除[],这两行按数据不同,可以选择
            # s = s.replace("'",'').replace(',','') +'\n'   #去除单引号,逗号,每行末尾追加换行符
            s = s.replace("'",'') +'\n'   #去除单引号,逗号,每行末尾追加换行符
            print(s)
            fileobj.write(s)
print("保存文件成功")

def urlFromtext(inpputfile,outFileDF):
    # 读取txt文件数据形式: 感动,每一天,http://www.***u.com/2019/happy.html
    interaldata = pd.read_csv(inpputfile, header=None, sep=',', low_memory=False)
    # 过滤无效数据
    filtdata =  interaldata.dropna()
    print(filtdata.head())
    # 查看数据框的行数
    print(filtdata.index.size)
    # 只采集含有关键字的数据-针对某一列
    bool = filtdata.iloc[:,0].str.contains('感动')
    filter_data = filtdata[bool]
    print(filter_data)
    print(filter_data.index.size)
    for index, row in filter_data.iterrows():
         # urldata= row.iloc[2].trim()
        urldata= row.iloc[2]
        levelname ='citytr'
        tmp2= (row.iloc[1],row.iloc[0])
        Datalist = parseURLData(urldata,levelname,tmp2)
        Datalist.to_csv(outFileDF, index=False, mode='a',header=False)

if __name__ == "__main__":
    rawUrl = '**********/32.html'
    levelKey = "citytr"
    # 解析的数据存储
    resultURL = parseURLData(rawUrl, levelKey, "每一天")
    filenameDF = "D:\\Coding\\Python\urlDF.txt"
    text_save(filenameDF,resultURL)

后续

还有一些技术上的问题,记下来,作为
01.HTML网页的缓存技术
02.URL的去重等
03.并行爬取的技术-多进程线程爬虫
04.回调函数的一些应用
05.lxml的解析方式
06.中断与恢复的情况

一些总结点

在对数据的输入-all input is bad until proven otherwise.
对输入做检查,对返回值的一些情况做预估,并做好防御性编程

blogroll

social