一个初初初学者的python爬虫心得

准备工作

  1. python基础知识,大概懂语法就ok;
  2. 网页相关知识,或许不是很重要,能看懂审查元素结果;
  3. IDE,我用Spyder,听说Sublime也好用,但是我搭建环境安装Package Control插件的时候凉掉了。。。上课用的Pycharm,可以Ctrl+左键查看方法的参数,对我这种小白很友好,而且下载和配置都很简单,好用!
  4. 过程中会使用pip命令安装Python相应的包和模块,所以打开命令行程序输入pip查看是否安装pip以及配置环境变量。看有朋友说windows下默认安装了pip工具,只是没有将路径加入path中;
  5. Mysql,不必须,将爬取的数据存储到数据库中会用到。

取一(书籍信息直接显示在html文件中)

我们以爬取当*网的500本书的书名、价格及作者信息并存储为.txt文件为例

  1. 分析网页结构
    审查元素结果
    可以看到每本书的书籍信息在<li></li>元素中,id="component_59"的<ul></ul>标签是其共同的父标签,每个网页有60本书,通过page_index值翻页
    针对每一本书
    每本书审查元素结果
    书籍名称、价格和作者存储在不同的标签中,我们要做的就是拿到这些标签的相应属性值或内容
  2. 步骤
    下载网页以得到网页源码
    import requests  #pip list命令查看相应包是否已下载,没有的话pip install 包名
    from lxml.html import fromstring
    def downloag_code(url): 
     response=requests.get(url)       #<class 'requests.models.Response'>
     htmlString=response.text         #<class='str'>
     code=fromstring(htmlString)      #<class 'lxml.html.HtmlElement'> 可以直接按照网页层次结构解析
     return code
    
    数据提取
    #获取一个网页的60本书
    def get_books(code,count,lonum):    
     li_list=code.xpath('..//ul[@id="component_59"]/li')  #获取<li></li>标签 <class='list'>
     books_list=[]         #存储当前网页的60本书
     for li in li_list:
         bookname=li.xpath('p[@class="name"]/a/@title') 
         price = li.xpath('p[@class="price"]/span[@class="search_now_price"]/text()')#有可能没有值
         author = li.xpath('p[@class="search_book_author"]/span/a[@name="itemlist-author"]/@title')
         if len(price)==0: #简单处理没有爬取到价格的书籍,问题在于存储位置不同,当然可以重新定位
             price=['¥46.60']
         books_list.append([bookname,price,author])
         lonum+=1  #控制爬取数据数目
         if lonum>count:
             return books_list
     return books_list
    
    #获取指定数目书籍
    def get_all_books(count):       #获取9个网页的书籍
     pages=math.ceil(count/60)    #每个网页60本书信息
     all_books=[]
     for page in range(1,pages+1):
         url="http://search.dangdang.com/?key=python&act=input&page_index={}".format(page) 
         codes=downloag_code(url)
         books_list=get_books(codes,count,(page-1)*60+1) #参数为源码,总数,当前开始的数目
         all_books.append(books_list)
     return all_books
    
    数据存储
    def save_all_books(all_books):
     with open(file="dangdang.txt",mode='w',encoding='utf_8') as file
     for page,books in enumerate(all_books):#写入方式2
         for num,book in enumerate(books):
             file.write("第{}页第{}条书籍是:{} \n".format(page+1,num+1,book))
    
    执行及结果
    if __name__=="__main__":
     all_books=get_all_books(180) #也可以修改网页地址其他属性如key获取不同书
     save_all_books(all_books)
    
    执行结果
取二(在刷新网页时加载js文件)

以智*招聘为例,审查元素时在network中寻找XHR文件,最终确定url
zhilian
可以看到data中定义了results列表存放职位信息,每个职位的信息组成字典类型

#获取源码
def downloag_code(url):   
   response=requests.get(url)
   jsoncode=response.json()       #字典形式
   return jsoncode
def get_values(jsoncode):
   jobs=jsoncode['data']['results']      #针对字典的读取形式
   vocations=[]
   for job in jobs:
       jobname=job['jobName']
       workexp=job['workingExp']['name']
       salary=job['salary']
       vocations.append((jobname,workexp,salary))
   return vocations
code=downloag_code("https://fe-api.zhaopin.com/c/i/sou?&start=90&pageSize=90&cityId=854&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=java&kt=3&_v=0.46880996&x-zp-page-request-id=2c5e1c1b0a3f448996ce61acf87be46d-1562292190264-205445&x-zp-client-id=5eaebb71-95e9-426d-8b07-7315576a86e7")  #preview中查看url
取三(加载时展示部分网页,进行操作后显示其余部分)

以一*店为例,在网页加载完毕时只显示30本书,浏览到底部会加载剩余的30本书
需要用到对应浏览器的驱动器,下载解压后将其添加到Mysql的bin目录下

from lxml.html import fromstring
from selenium import webdriver
import time
def downloag_code(url):   #获取一个网页源码
    # 1- 启动谷歌浏览器
    chrome = webdriver.Chrome()
    # 2- url
    chrome.get(url)
    # 3- 缓冲时间(打开网页)
    time.sleep(3)
    # 4- 滚动条的执行,执行一个js代码,实现滚动条的滚动
    js="window.scrollTo(0,100000)" #需要足够的长度,否则不能触发,加载可以用循环实现
    chrome.execute_script(js)
    time.sleep(3)          #(滚动后浏览器自身的缓冲)
    # 5- 获取内容
    code=chrome.page_source        
    htmlcode=fromstring(code)
    return htmlcode

上面的代码提到了存储在记事本中,这里再记录一下存储到数据库中,以及导入到Excel表中

1.数据库

在存储之前首先需要设置好数据库一系列内容。
我建立了名为dangd的数据库,并创建了一个books的表

"""
建表
create table books(
bid int primary key auto_increment,
bname varchar(255) not null,
bprice float(20),
bauthor varchar(300)
)engine="InnoDb" charset="utf8";
"""
#1-导包
import pymysql
from demo2.dangd import downloag_code,get_books,get_all_books  
#2-建立连接
connect=pymysql.connect(host="localhost",port=3306,user="root",password="12345",database="dangd",charset="utf8")
#3-操作之需求
sql="insert into books(bname,bprice,bauthor)values (%s,%s,%s)"
#操作之执行者
cursor=connect.cursor()
#操作之执行
all_books=get_all_books(30)
for books in all_books:
    for book in books:
        row=cursor.execute(sql,[book[0],book[1][0][1:],str(book[2])])    
#4-结果处理:成功则提交,失败则回滚
        if row>0:
            connect.commit()
        else:
            connect.rollback()
#5-关闭资源
cursor.close()
connect.close()
2.Excel
import xlwt
def save_to_excel():
    #1-创建工作表
    workbook=xlwt.Workbook(encoding='utf-8')  
    #2-添加sheet文件
    sheet=workbook.add_sheet("dangpython",True)     
    #xlwt.Worksheet("dangpython",workbook,True)   
    # 3-写内容 sheet 行列从0开始标号
    all_books=get_all_books(200)  #获取200本书信息
    row=0  #控制写入工作表的行
    for books in all_books:
        for book in books:
            for i in range(len(book)):
                sheet.write(row, i, book[i])
            row+=1
    #4-保存(在同一目录下)
    workbook.save("dangd.xls")

数据可视化

对存储到数据库中的数据进行处理
可以调用matplotlib中的方法实现如折线图、饼图和条形图等的绘制
以条形图为例,比较每个价格区间的最大值和最小值
首先在数据库中建立关于价格区间的视图

'''
create view temp_bprice(bprice,pricerange) as
select bprice,case
when bprice<50 then "0-50"
when bprice<100 then "50-100"
when bprice<150 then "100-150"
when bprice<200 then "150-200"
when bprice>=200 then "200及以上"
end pricerange from books
'''
import pymysql
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties   #设置中文字体
#获取最大值和最小值列表
def getxyz():
	#省略数据库相关操作
    #sql="""select pricerange,min(bprice),max(bprice) from temp_bprice group by pricerange order by max(bprice)"""
    x=[]
    y_min=[]  #最大值列表
    y_max=[]  #最小值列表
    for i in result:
         x.append(i[0])
         y_min.append(i[1])
         y_max.append(i[2])
    return x,y_min,y_max
#绘图
def get_bar(x,y,z):
    font = FontProperties(fname="..\\toolsf\\STXINGKA.TTF")#为字体创建对象
    x_axis = [i - 0.15 for i in range(len(x))]
    plt.bar(x_axis,y,width=0.3,color='blue')
    x_axis = [i + 0.15 for i in range(len(x))]
    plt.bar(x_axis,z,width=0.3,color='purple')
    plt.xticks(range(len(x)), x, fontproperties=font,rotation=30)#旋转刻度
    plt.xlabel('图书价格区间',fontproperties=font)
    plt.ylabel('数量',fontproperties=font)
    plt.title("图书价格条形图",fontproperties=font)
    plt.show()

条形图

词云图

只是学习了一点皮毛,权当做个记录

from wordcloud import WordCloud
import pymysql
from PIL import Image   #读取图像信息
import numpy            #科学计算第三方工具
import matplotlib.pyplot as plt

def get_text():
    text=""
    #省略数据库一般操作
    #sql = """select bname from books"""
    return text
def get_wordcloud(text):
    img=Image.open("1.jpg")       #类似PS中的蒙版(个人理解)
    mask_img=numpy.array(img)
    wordcloud=WordCloud(font_path="..\\toolsf\\STXINGKA.TTF",
    	background_color="white", width=200,mask=mask_img,
    	stopwords=['Python','第2版','第3版'],)#stopwords:不显示的词语
    #词云图的生成
    wordcloud=wordcloud.generate(text)
    #保存
    wordcloud.to_file("wordcloud.png")

结果。。。
词云
为什么这么奇怪呢,大概是因为我用了这样一张图?。。。(图源:百度)

后记

可以看到基本都遵循相同的步骤,能否爬到需要的数据还是在于对网页结构的分析
其余什么参数之类可以查看文档
人生第一次写这种总结性的东西,想着也是对自己学到的东西的记录。毕竟菜鸡如我指不定哪天就忘了
做事情从来都是三分钟热度,可求求我自己能多坚持一会
如果有大佬看见了,您可以说我哪错了,但不能说我菜,嗯
爬虫还要继续学习,毕竟早上看别人的Scrapy等等各种神奇框架没咋理解
我寻思着这东西还挺有意思的,发人深省,那天爬了智联招聘各种工作岗位和月薪,啊,活着好难,挣钱好难

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值