博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用Python实现简单的爬虫
阅读量:6071 次
发布时间:2019-06-20

本文共 9671 字,大约阅读时间需要 32 分钟。

爬虫原理

网络连接需要计算机一次Request请求和服务器端的Response回应。爬虫也需要做两件事:

  • 模拟计算机对服务器发起Request请求
  • 接收服务器端的Response内容并解析、提取所需要的信息。

Python第三方库的安装

在PyCharm中安装

  • 打开PyCharm,在菜单栏中选择File|Default Settings 命令
  • 选择左侧的 Project Interpreter选项,在窗口右侧选择Python环境

  • 单击右侧窗口左下角的➕号添加第三方库
  • 输入三方库名称,选中需要下载的库

  • 单击 Install Package 按钮安装(注:Windows平台下需要勾选 Install to user sit 复选框)。

在PIP中安装

安装Python之后,PIP会同时进行安装,验证PIP是否安装成功

pip3 --version复制代码

安装Python三方库

pip3 install packagename复制代码

注:如果使用Python2,pip3改为 pip 使用

手动安装

  • 在网站下载所需要安装的库

  • 命令行中输入

pip3 install wheel复制代码
  • cd到所下载库在本地的位置执行命令行
pip3 install packagename.whl复制代码

推荐方法为 PIP安装本地手动安装 方式。

第一个简单的爬虫

利用 request获取网络数据,利用BeautifulSoup解析数据。获取的数据自如网站租房信息的房屋信息Title。

一段代码

import  requestsfrom  bs4 import BeautifulSoup #导入相应的库headers = {    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}#模拟浏览器请求头res = requests.get('http://www.ziroom.com/z/nl/-z3.html?qwd=%E4%BA%AE%E9%A9%AC%E6%A1%A5',headers = headers) #请求网页# print(res.text)soup = BeautifulSoup(res.text,'html.parser') # 解析数据# print(soup.prettify())# price = soup.select('#houseList > li:nth-child(2) > div.txt > h3')names = soup.select('#houseList > li:nth-of-type(2) > div.txt > h3')# print(name.getText())# names = soup.select('#houseList > li > div.txt > h3 > a')#for name in names:    print(name.getText())复制代码

代码分析:

  • 关于headers

加入请求头来伪装陈浏览器,以便更好的获取数据。User-Agent获取方式,打开开发者工具,刷新网页后即可获取

  • select方法
soup.select('div.item > a > h1') #括号中的内容可通过浏览器复制得到复制代码

(1)鼠标定位到需要提取数据的位置,右击选择“检查”命令

(2)在网页源码中右击所选元素,在弹出的菜单中选择“Copy selector”,可得到:

#houseList > li:nth-child(2) > div.txt > h3复制代码

注:

nth-child(2)中的2表示的是所取得是列表中的第二个数据。

这个在Python中运行会报错,需要将其改为nth-of-type(2)

如果需要获取整个列表的所有信息,只需将nth-of-type(2)去掉就可以了。像这样:

names = soup.select('#houseList > li > div.txt > h3 > a')复制代码
  • getText()方法

使用该方法获取文字信息。

使用前获取的数据是这样的

豪宅 · 星源汇1居室-西

复制代码

使用后获取的数据是这样的

豪宅 · 星源汇1居室-西复制代码
  • get('attr')

用来获取属性信息,此代码中暂未用到。

最后再来个稍微复杂的例子来说明更多使用小技巧,不解释了。

实现效果,获取酷狗Top500的歌曲信息

import requestsfrom bs4 import BeautifulSoupimport  timeheaders = {    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}def get_music(url):    res = requests.get(url,headers=headers)    # print(res.text)    # soup = BeautifulSoup(res.text,'lxml')    soup = BeautifulSoup(res.text, 'html.parser')    # print(soup.prettify())    ranks = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')    titles = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > a')    for rank , title in zip(ranks,titles): # 多个数据的处理方式        data = {            'rank' : rank.getText().strip(), # 字符串的处理方式,去除两侧的空格            'title' : title.getText(),        }        print(data)if __name__ == '__main__':    urls = ['http://www.kugou.com/yy/rank/home/{}-8888.html?from=rank'.format(str(i)) for i in range(1,24)]    i = 0    for url in urls:        i = i + 1        print('第{}页'.format(i))        get_music(url)        time.sleep(2) #以防数据获取速度太快出现问题复制代码

使用正则表达式来解析数据

正则表达式常用字符

一般字符

  • "." 匹配任意单个字符。例如 a.b ,可以匹配为abc、aic、a&c等,但不包含换行符
  • "" 转义字符,把字符改变为原来的意思。
  • [...] 字符集,相当于括号中任选一个。例如a[bcd],可以匹配为 ab、ac、ad。

预定义字符

数量词

  • "*" 匹配前一个字符0或无限次
  • "+" 至少匹配前一个字符一次
  • "?" 匹配前一个字符0次或者1次
  • "{m}" 匹配前一个字符 m 次
  • "{m,n}"匹配前一个字符m至n词

边界匹配

re模块

re模块拥有Python语言拥有的所有的正则表达式功能。

search()函数

用于匹配并提取第一个符合规律的内容。

语法如下:

re.search(pattern,string,flags=0)复制代码
  • pattern 为匹配的正则表达式
  • string 要匹配的字符串
  • flags 标志位,用于控制正则表达式的匹配方式,如是否区分大小写,多行匹配等。

例子:

import rea = 'one12twp2three33four'infos = re.search('\d+',a)print(infos) #  <_sre.SRE_Match object; span=(3, 5), match='12'>print(infos.group()) # group方法获取信息  12复制代码

sub()函数

用于替换字符串中的匹配项。

语法如下:

re.sub(pattern,repl,string,count=0,flags=0)复制代码
  • pattern 匹配的正则表达式
  • repl 替换的字符串
  • string 要被查找替换的原始字符串
  • count 模式匹配后替换的最大次数,默认0表示替换所有的匹配
  • flags 标志位,控制正则表达式的匹配方式

例子:

import rephone = '181-1324-1341'newphone = re.sub('\D+','',phone)print(newphone) #18113241341复制代码

findall()函数

匹配所有符合规律的内容,并以列表的形式返回结果。

例子:

import rea = 'one12twp2three33four'infos = re.findall('\d+',a)print(infos) #['12', '2', '33']infos = re.findall('\d',a)print(infos)  #['1', '2', '2', '3', '3']复制代码

完整的示例

获取斗破苍穹小说全部内容并存到本地文件中

import  requestsimport reimport timef = open('/Users/fangjiayou/Desktop/Last/untitled001.txt','a+')def get_info(url):    req = requests.get(url)    if req.status_code == 200:        contents = re.findall('

(.*?)

',req.content.decode('utf-8'),re.S) for content in contents: f.write(content+'\n\n') else: passif __name__ == '__main__': urls = ['http://www.doupoxs.com/doupocangqiong/{}.html'.format(str(number)) for number in range(2,1625)] for url in urls: print(url) get_info(url) f.close() #关闭文件,防止内存问题复制代码

Lxml库的使用并存放数据到excel中

三方库 xlwt的使用

写入Excel中需要的三方库

pip3 install xlwt复制代码

使用方式

import  xlwtbook = xlwt.Workbook(encoding='utf-8') # 创建工作簿sheet = book.add_sheet('Sheet1') # 创建工作表sheet.write(0,0,'python') # 在相应的单元格写入数据sheet.write(1,1,'love')book.save('test.xls') # 保存到文件中复制代码

实现效果:

举例 获取起点中文网小说信息

包含了lxml解析方式的使用

先上代码

import  xlwtimport requestsimport  timefrom lxml import  etreeall_info_list = [] # 初始化列表,存入爬虫数据def get_info(url): # 定义获取爬虫信息的函数    req = requests.get(url)    html = etree.HTML(req.text)    infos = html.xpath('//ul[@class="all-img-list cf"]/li')# 定位大标签,一次循环    for info in infos:        title = info.xpath('div[2]/h4/a/text()')[0]        author = info.xpath('div[2]/p[1]/a[1]/text()')[0]        complete = info.xpath('div[2]/p[1]/span/text()')[0]        introduce = info.xpath('div[2]/p[2]/text()')[0].strip()        info_list = [title,author,complete,introduce]        all_info_list.append(info_list)        print(info_list)    time.sleep(1) # 睡眠1sif __name__ == '__main__':    urls = ['https://www.qidian.com/all?orderId=&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=0&page={}'.format(str(number)) for number in range(0,2)]    for url in  urls:        get_info(url)    header = ['书名','作者','结束','简介']    book = xlwt.Workbook(encoding='utf-8') # 创建工作簿    sheet = book.add_sheet('Sheet1') #创建工作表    for h in  range(len(header)):        sheet.write(0,h,header[h]) # 写入表头    row = 1    for list in  all_info_list:        colum = 0        for data in list:            sheet.write(row,colum,data)            colum = colum + 1        row = row + 1    book.save('起点小说.xls') #保存文件复制代码

解析JSON数据

Python中有解析JSON数据的标准库,使用方式:

import json复制代码

使用方法很简单,只需一段代码说明:

import jsonjsonstring = '{"user_man":[{"name":"peter"},{"name":"xiaoming"}],'\    '"user_woman":[{"name":"Anni"},{"name":"zhangsan"}]}'jsondata = json.loads(jsonstring)print(jsondata.get("user_man")) #[{'name': 'peter'}, {'name': 'xiaoming'}]print(jsondata.get('user_woman')[0].get('name')) #Anni复制代码

如何爬取图片

使用URLretrieve模块

URLretrieve模块是URLlib.request中的一部分,用法:

urlretrieve(url,path)复制代码

使用代码示例:

path = '/Users/fang/Desktop/Last/'urlstr = 'http://g.hiphotos.baidu.com/image/h%3D300/sign=fb8af6169d2397ddc9799e046983b216/0823dd54564e92584fbb491f9082d158cdbf4eb0.jpg'urlretrieve(urlstr,path+urlstr[-10:])复制代码

通过写入文件来获取图片

path = '/Users/fangjiayou/Desktop/Last/'urlstr = 'http://g.hiphotos.baidu.com/image/h%3D300/sign=fb8af6169d2397ddc9799e046983b216/0823dd54564e92584fbb491f9082d158cdbf4eb0.jpg'data = requests.get(urlstr)fp = open(path+urlstr[-10:],'wb')fp.write(data.content)fp.close()复制代码

解析JSON数据并获取图片

示例流程为:根据关键词搜索对应的图片,解析数据进行图片下载。

代码:

from bs4 import BeautifulSoupimport requestsimport jsonheader = {    'accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}searchPicURL = 'https://www.pexels.com/search/'word = input('请输入要下载的图片:')url = searchPicURL+wordprint(url)data = requests.get(url)soup = BeautifulSoup(data.text,'lxml')images = soup.select('body > div.page-wrap > div.l-container > div.photos > article > a.js-photo-link > img')path = '/Users/fangjiayou/Desktop/Last/'i = 1for image in  images:    print('开始写入第{}张'.format(i))    src = image.get('src')    data = requests.get(src)    relativepath = path+src.split('?')[0][-10:]    fp = open(relativepath,'wb')    fp.write(data.content)    fp.close()    print('第{}张写入结束'.format(i))    i = i + 1复制代码

多线程的使用

Python中多线程爬虫使用multiprocess库,

使用方法:

from multiprocess import Pooldef method(url):    print(url)pool = Pool(processes=4)pool.map(method,['1','2','3'])# method 为需要运行的函数,后面为迭代参数复制代码

通过爬取糗事百科数据来说明使用多线程的效率提升,代码如下

import requestsimport refrom multiprocess import Poolimport timeheaders = {    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}def re_scraper(url):    req = requests.get(url,headers=headers)    titles = re.findall('

(.*?)

',req.text,re.S) contents = re.findall('
\n
(.*?)',req.text,re.S) # for title,content in zip(titles,contents): # print('Title:'+title+'\nContent:'+content)if __name__ == '__main__': urls = ['https://www.qiushibaike.com/text/page/{}/'.format(str(page)) for page in range(1,30)] print("开始串行爬虫") start1 = time.time() for url in urls: re_scraper(url) end1 = time.time() print('串行爬虫消耗时间:',end1-start1) print('两个线程开始') start2 = time.time() pool2 = Pool(processes=2) pool2.map(re_scraper,urls) end2 = time.time() print('两个线程消耗时间:',end2-start2) print('四个线程开始') start4 = time.time() pool4 = Pool(processes=4) pool4.map(re_scraper, urls) end4 = time.time() print('四个线程消耗时间:', end4 - start4)复制代码

结果如下:

开始串行爬虫串行爬虫消耗时间: 5.8548901081085205两个线程开始两个线程消耗时间: 2.986906051635742四个线程开始四个线程消耗时间: 1.016632080078125复制代码

注:并不是线程越多效率越高,根据硬件设置线程数才是最好的选择

----------------------------持续更新---------------------------

转载地址:http://wsbgx.baihongyu.com/

你可能感兴趣的文章
ThreadPoolExecutor线程池运行机制分析-线程复用原理
查看>>
React Native 极光推送填坑(ios)
查看>>
Terratest:一个用于自动化基础设施测试的开源Go库
查看>>
修改Windows远程终端默认端口,让服务器更安全
查看>>
扩展器必须,SAS 2.0未必(SAS挺进中端存储系统之三)
查看>>
Eclipse遇到Initializing Java Tooling解决办法
查看>>
while((ch = getchar()) != '\n')
查看>>
好程序员web前端分享JS检查浏览器类型和版本
查看>>
Linux 安装oracle内核参数
查看>>
Oracle DG 逻辑Standby数据同步性能优化
查看>>
exchange 2010 队列删除
查看>>
android实用测试方法之Monkey与MonkeyRunner
查看>>
「翻译」逐步替换Sass
查看>>
H5实现全屏与F11全屏
查看>>
处理excel表的列
查看>>
枸杞子也能控制脂肪肝
查看>>
Excuse me?这个前端面试在搞事!
查看>>
C#数据采集类
查看>>
quicksort
查看>>
检验函数运行时间
查看>>