一个初初初学者的python爬虫心得
准备工作
- python基础知识,大概懂语法就ok;
- 网页相关知识,或许不是很重要,能看懂审查元素结果;
- IDE,我用Spyder,听说Sublime也好用,但是我搭建环境安装Package Control插件的时候凉掉了。。。上课用的Pycharm,可以Ctrl+左键查看方法的参数,对我这种小白很友好,而且下载和配置都很简单,好用!
- 过程中会使用pip命令安装Python相应的包和模块,所以打开命令行程序输入pip查看是否安装pip以及配置环境变量。看有朋友说windows下默认安装了pip工具,只是没有将路径加入path中;
- Mysql,不必须,将爬取的数据存储到数据库中会用到。
取
取一(书籍信息直接显示在html文件中)
我们以爬取当*网的500本书的书名、价格及作者信息并存储为.txt文件为例
- 分析网页结构
可以看到每本书的书籍信息在<li></li>元素中,id="component_59"的<ul></ul>标签是其共同的父标签,每个网页有60本书,通过page_index值翻页
针对每一本书
书籍名称、价格和作者存储在不同的标签中,我们要做的就是拿到这些标签的相应属性值或内容 - 步骤
下载网页以得到网页源码
数据提取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
可以看到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等等各种神奇框架没咋理解
我寻思着这东西还挺有意思的,发人深省,那天爬了智联招聘各种工作岗位和月薪,啊,活着好难,挣钱好难