python爬虫下载函数 python爬虫app数据抓取

Python编程基础之(五)Scrapy爬虫框架 经过前面四章的学习python爬虫下载函数,我们已经可以使用Requests库、Beautiful Soup库和Re库,编写基本的Python爬虫程序python爬虫下载函数了 。那么这一章就来学习一个专业的网络爬虫框架--Scrapy 。没错,是框架 , 而不是像前面介绍的函数功能库 。
Scrapy是一个快速、功能强大的网络爬虫框架 。
可能大家还不太了解什么是框架,爬虫框架其实是实现爬虫功能的一个软件结构和功能组件的集合 。
简而言之,Scrapy就是一个爬虫程序的半成品,可以帮助用户实现专业的网络爬虫 。
使用Scrapy框架,不需要python爬虫下载函数你编写大量的代码,Scrapy已经把大部分工作都做好了 , 允许你调用几句代码便自动生成爬虫程序,可以节省大量的时间 。
当然,框架所生成的代码基本是一致的 , 如果遇到一些特定的爬虫任务时,就不如自己使用Requests库搭建来的方便了 。
PyCharm安装
测试安装:
出现框架版本说明安装成功 。
掌握Scrapy爬虫框架的结构是使用好Scrapy的重中之重!
先上图:
整个结构可以简单地概括为: “5 2”结构和3条数据流
5个主要模块(及功能):
(1)控制所有模块之间的数据流 。
(2)可以根据条件触发事件 。
(1)根据请求下载网页 。
(1)对所有爬取请求进行调度管理 。
(1)解析DOWNLOADER返回的响应--response 。
(2)产生爬取项--scraped item 。
(3)产生额外的爬取请求--request 。
(1)以流水线方式处理SPIDER产生的爬取项 。
(2)由一组操作顺序组成,类似流水线,每个操作是一个ITEM PIPELINES类型 。
(3)清理、检查和查重爬取项中的HTML数据并将数据存储到数据库中 。
2个中间键:
(1)对Engine、Scheduler、Downloader之间进行用户可配置的控制 。
(2)修改、丢弃、新增请求或响应 。
(1)对请求和爬取项进行再处理 。
(2)修改、丢弃、新增请求或爬取项 。
3条数据流:
(1):图中数字 1-2
1:Engine从Spider处获得爬取请求--request 。
2:Engine将爬取请求转发给Scheduler,用于调度 。
(2):图中数字 3-4-5-6
3:Engine从Scheduler处获得下一个要爬取的请求 。
4:Engine将爬取请求通过中间件发送给Downloader 。
5:爬取网页后,Downloader形成响应--response , 通过中间件发送给Engine 。
6:Engine将收到的响应通过中间件发送给Spider处理 。
(3):图中数字 7-8-9
7:Spider处理响应后产生爬取项--scraped item 。
8:Engine将爬取项发送给Item Pipelines 。
9:Engine将爬取请求发送给Scheduler 。
任务处理流程:从Spider的初始爬取请求开始爬取,Engine控制各模块数据流,不间断从Scheduler处获得爬取请求,直至请求为空 , 最后到Item Pipelines存储数据结束 。
作为用户,只需配置好Scrapy框架的Spider和Item Pipelines,也就是数据流的入口与出口,便可完成一个爬虫程序的搭建 。Scrapy提供了简单的爬虫命令语句,帮助用户一键配置剩余文件,那我们便来看看有哪些好用的命令吧 。
Scrapy采用命令行创建和运行爬虫
PyCharm打开Terminal,启动Scrapy:
Scrapy基本命令行格式:
具体常用命令如下:
下面用一个例子来学习一下命令的使用:
1.建立一个Scrapy爬虫工程 , 在已启动的Scrapy中继续输入:
执行该命令,系统会在PyCharm的工程文件中自动创建一个工程,命名为pythonDemo 。
2.产生一个Scrapy爬虫,以教育部网站为例:
命令生成了一个名为demo的spider,并在Spiders目录下生成文件demo.py 。
命令仅用于生成demo.py文件 , 该文件也可以手动生成 。
观察一下demo.py文件:
3.配置产生的spider爬虫,也就是demo.py文件:
4.运行爬虫,爬取网页:
如果爬取成功 , 会发现在pythonDemo下多了一个t20210816_551472.html的文件,我们所爬取的网页内容都已经写入该文件了 。
以上就是Scrapy框架的简单使用了 。
Request对象表示一个HTTP请求,由Spider生成 , 由Downloader执行 。
Response对象表示一个HTTP响应,由Downloader生成,有Spider处理 。
Item对象表示一个从HTML页面中提取的信息内容 , 由Spider生成,由Item Pipelines处理 。Item类似于字典类型,可以按照字典类型来操作 。
python爬虫的工作步骤当前处于一个大数据的时代,一般网站数据来源有二python爬虫下载函数:网站用户自身产生的数据和网站从其他来源获取的数据,今天要分享的是如何从其他网站获取python爬虫下载函数你想要的数据 。
目前最适合用于写爬虫的语言是python , python中最受欢迎的爬虫框架是scrapy,本文围绕scrapy来展开讲解爬虫是怎么工作的 。
1.如下图所示,爬虫从编写的spider文件中的start_urls开始,这个列表中的url就是爬虫抓取的第一个网页,它的返回值是该url对应网页的源代码 , 我们可以用默认的parse(self,response)函数去打印或解析这个源代码
2.我们获取到源代码之后,就可以从网页源代码中找到我们想要的信息或需要进一步访问的url,提取信息这一步,scrapy中集成了xpath,正则(re),功能十分强大,提取到信息之后会通过yield进入到中间件当中 。
中间件包括爬虫中间件和下载中间件,爬虫中间件主要用于设置处理爬虫文件中的代码块,下载中间件主要用于判断爬虫进入网页前后的爬取状态,在此中间件中,你可以根据爬虫的返回状态去做进一步判断 。
最后我们将yield过来的item , 即就是我们想要的数据会在pipeline.py文件中进行处理,存入数据库,写入本地文件 , 都可以在这里进行 , 另外,为了减少代码冗余,建议所有与设置参数有关的参数 , 都写在settings.py中去
Python3.xx中写爬虫,下载图片除了urlretrieve方法 , 还有什么库的什么方法呢?Part 1. urllib2
urllib2是Python标准库提供的与网络相关的库,是写爬虫最常用的一个库之一 。
想要使用Python打开一个网址,最简单的操作即是:
your_url = ""html = urllib2.urlopen(your_url).read()12
这样所获得的就是对应网址(url)的html内容了 。
但有的时候这么做还不够,因为目前很多的网站都有反爬虫机制 , 对于这么初级的代码 , 是很容易分辨出来的 。例如本文所要下载图片的网站,上述代码会返回HTTPError: HTTP Error 403: Forbidden错误 。
那么,在这种情况下,下载网络图片的爬虫(虽然只有几行代码 , 但一个也可以叫做爬虫了吧,笑),就需要进一步的伪装 。
要让爬虫伪装成浏览器访问指定的网站的话,就需要加入消息头信息 。所谓的消息头信息就是在浏览器向网络服务器发送请求时一并发送的请求头(Request Headers)信息和服务器返回的响应头(Response Headers)信息 。
例如,使用FireFox打开时所发送的Request Headers的部分内容如下:
Host:"publicdomainarchive.com/"User-Agent:"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0"Accept:"text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8"...1234
还有一些其他属性,但其中伪装成浏览器最重要的部分已经列出来了,即User-Agent信息 。
要使用Headers信息,就不能再仅仅向urlopen方法中传入一个地址了 , 而是需要将HTTP Request的Headers封装后传入:
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'}req = urllib2.Request(url = url, headers = headers)content = urllib2.urlopen(req).read()123
这样 , 就获得了网站的html内容 。
接下来,就需要从html去获取图片的链接 。
Part 2. HTMLParser
HTMLParser是Python提供的HTML解析库之一 。
但Python提供的这个类中很多方法都没有实现,因而基本上这个库只负责进行解析,但解析完了什么都不做 。所以如果需要对HTML中的某些元素进行加工的话,就需要用户自己去实现其中的一些方法 。本文仅实现其中的handle_starttag方法:
class MyHTMLParser(HTMLParser): #继承HTMLParser类
def __init__(self):#初始化
HTMLParser.__init__(self)def handle_starttag(self, tag, attrs):
#参数tag即由HTMLParser解析出的开始标签 , attrs为该标签的属性
【python爬虫下载函数 python爬虫app数据抓取】if tag == "img":#下载图片所需要的img标签
if len(attrs) == 0: pass
else:for (variable, value)in attrs:#在attrs中找到src属性,并确定其是我们所要下载的图片,最后将图片下载下来(这个方法当然也有其他的写法)
if variable == "src" and value[0:4] == 'http' and value.find('x') = 0:
pic_name = value.split('/')[-1]print pic_name
down_image(value, pic_name)123456789101112131415
Part 3. 下载图片
从handle_starttag方法中,我们已经获得了图片的url , 那么,最后一步,我们要下载图片了 。
当然,要获得网络上的图片,自然也需要向服务器发送请求,一样需要用到urllib2这个库,也需要用到上面所用到的请求头 。
以下是down_image()方法的主要代码:
binary_data = https://www.04ip.com/post/urllib2.urlopen(req).read()
temp_file = open(file_name, 'wb')
temp_file.write(binary_data)
temp_file.close()1234
因为这次打开的网址是个图片,所以urllib2.urlopen(req).read()所获取的就是图片的数据,将这些数据需要以二进制的方式写入本地的图片文件 , 即将图片下载下来了 。
因为图片的url的最后一部分是图片的名字 , 所以可以直接用做本地的文件名 , 不用担心命名冲突,也不用担心后缀不符,很是方便 。
Part 4. getFreeImages.py
这个下载图片的脚本的完整代码如下:
import urllib2,osfrom HTMLParser import HTMLParser
class MyHTMLParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)#self.links = {}
def handle_starttag(self, tag, attrs):
#print "Encountered the beginning of a %s tag" % tag
if tag == "img":if len(attrs) == 0: pass
else:for (variable, value)in attrs:if variable == "src" and value[0:4] == 'http' and value.find('x') = 0:
pic_name = value.split('/')[-1]print pic_name
down_image(value, pic_name)def down_image(url,file_name):
global headers
req = urllib2.Request(url = url, headers = headers)
binary_data = https://www.04ip.com/post/urllib2.urlopen(req).read()
temp_file = open(file_name, 'wb')
temp_file.write(binary_data)
temp_file.close()if __name__ == "__main__":
img_dir = "D:\\Downloads\\domain images"
if not os.path.isdir(img_dir):
os.mkdir(img_dir)
os.chdir(img_dir)print os.getcwd()
url = ""
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'}
all_links = []
hp = MyHTMLParser()for i in range(1,30):
url = ''str(i)'/'
req = urllib2.Request(url = url, headers = headers)
content = urllib2.urlopen(req).read()
hp.feed(content)
hp.close()1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
如何用Python做爬虫1)首先你要明白爬虫怎样工作 。
想象你是一只蜘蛛,现在你被放到了互联“网”上 。那么,你需要把所有的网页都看一遍 。怎么办呢?没问题呀 , 你就随便从某个地方开始,比如说人民日报的首页,这个叫initial pages,用$表示吧 。
在人民日报的首页,你看到那个页面引向的各种链接 。于是你很开心地从爬到了“国内新闻”那个页面 。太好了,这样你就已经爬完了俩页面(首页和国内新闻)!暂且不用管爬下来的页面怎么处理的,你就想象你把这个页面完完整整抄成了个html放到了你身上 。
突然你发现, 在国内新闻这个页面上,有一个链接链回“首页” 。作为一只聪明的蜘蛛,你肯定知道你不用爬回去的吧,因为你已经看过了啊 。所以,你需要用你的脑子,存下你已经看过的页面地址 。这样,每次看到一个可能需要爬的新链接,你就先查查你脑子里是不是已经去过这个页面地址 。如果去过,那就别去了 。
好的,理论上如果所有的页面可以从initial page达到的话,那么可以证明你一定可以爬完所有的网页 。
那么在python里怎么实现呢?
很简单
import Queue
initial_page = "初始化页"
url_queue = Queue.Queue()
seen = set()
seen.insert(initial_page)
url_queue.put(initial_page)
while(True): #一直进行直到海枯石烂
if url_queue.size()0:
current_url = url_queue.get()#拿出队例中第一个的url
store(current_url)#把这个url代表的网页存储好
for next_url in extract_urls(current_url): #提取把这个url里链向的url
if next_url not in seen:
seen.put(next_url)
url_queue.put(next_url)
else:
break
写得已经很伪代码了 。
所有的爬虫的backbone都在这里,下面分析一下为什么爬虫事实上是个非常复杂的东西——搜索引擎公司通常有一整个团队来维护和开发 。
2)效率
如果你直接加工一下上面的代码直接运行的话,你需要一整年才能爬下整个豆瓣的内容 。更别说Google这样的搜索引擎需要爬下全网的内容了 。
问题出在哪呢?需要爬的网页实在太多太多了,而上面的代码太慢太慢了 。设想全网有N个网站,那么分析一下判重的复杂度就是N*log(N) , 因为所有网页要遍历一次,而每次判重用set的话需要log(N)的复杂度 。OK,OK,我知道python的set实现是hash——不过这样还是太慢了 , 至少内存使用效率不高 。
通常的判重做法是怎样呢?Bloom Filter. 简单讲它仍然是一种hash的方法,但是它的特点是,它可以使用固定的内存(不随url的数量而增长)以O(1)的效率判定url是否已经在set中 。可惜天下没有白吃的午餐,它的唯一问题在于 , 如果这个url不在set中,BF可以100%确定这个url没有看过 。但是如果这个url在set中,它会告诉你:这个url应该已经出现过,不过我有2%的不确定性 。注意这里的不确定性在你分配的内存足够大的时候,可以变得很小很少 。一个简单的教程:Bloom Filters by Example
注意到这个特点,url如果被看过,那么可能以小概率重复看一看(没关系 , 多看看不会累死) 。但是如果没被看过,一定会被看一下(这个很重要,不然我们就要漏掉一些网页了?。?。[IMPORTANT: 此段有问题,请暂时略过]
好,现在已经接近处理判重最快的方法了 。另外一个瓶颈——你只有一台机器 。不管你的带宽有多大,只要你的机器下载网页的速度是瓶颈的话,那么你只有加快这个速度 。用一台机子不够的话——用很多台吧!当然,我们假设每台机子都已经进了最大的效率——使用多线程(python的话,多进程吧) 。
3)集群化抓取
爬取豆瓣的时候,我总共用了100多台机器昼夜不停地运行了一个月 。想象如果只用一台机子你就得运行100个月了...
那么 , 假设你现在有100台机器可以用,怎么用python实现一个分布式的爬取算法呢?
我们把这100台中的99台运算能力较小的机器叫作slave,另外一台较大的机器叫作master , 那么回顾上面代码中的url_queue,如果我们能把这个queue放到这台master机器上,所有的slave都可以通过网络跟master联通,每当一个slave完成下载一个网页,就向master请求一个新的网页来抓取 。而每次slave新抓到一个网页,就把这个网页上所有的链接送到master的queue里去 。同样,bloom filter也放到master上,但是现在master只发送确定没有被访问过的url给slave 。Bloom Filter放到master的内存里,而被访问过的url放到运行在master上的Redis里,这样保证所有操作都是O(1) 。(至少平摊是O(1),Redis的访问效率见:LINSERT – Redis)
考虑如何用python实现:
在各台slave上装好scrapy , 那么各台机子就变成了一台有抓取能力的slave,在master上装好Redis和rq用作分布式队列 。
代码于是写成
#slave.py
current_url = request_from_master()
to_send = []
for next_url in extract_urls(current_url):
to_send.append(next_url)
store(current_url);
send_to_master(to_send)
#master.py
distributed_queue = DistributedQueue()
bf = BloomFilter()
initial_pages = ""
while(True):
if request == 'GET':
if distributed_queue.size()0:
send(distributed_queue.get())
else:
break
elif request == 'POST':
bf.put(request.url)
好的,其实你能想到,有人已经给你写好了你需要的:darkrho/scrapy-redis · GitHub
4)展望及后处理
虽然上面用很多“简单” , 但是真正要实现一个商业规模可用的爬虫并不是一件容易的事 。上面的代码用来爬一个整体的网站几乎没有太大的问题 。
但是如果附加上你需要这些后续处理,比如
有效地存储(数据库应该怎样安排)
有效地判重(这里指网页判重,咱可不想把人民日报和抄袭它的大民日报都爬一遍)
有效地信息抽?。ū热缭趺囱槿〕鐾成纤械牡刂烦槿〕隼矗俺羟芙分谢馈保?搜索引擎通常不需要存储所有的信息,比如图片我存来干嘛...
及时更新(预测这个网页多久会更新一次)
如你所想,这里每一个点都可以供很多研究者十数年的研究 。虽然如此 ,
“路漫漫其修远兮,吾将上下而求索” 。
所以,不要问怎么入门,直接上路就好了:)
Python爬虫实战,Python多线程抓取5千多部最新电影下载链接利用Python多线程爬了5000多部最新电影下载链接,废话不多说~
让我们愉快地开始吧~
Python版本:3.6.4
相关模块:
requests模块;
re模块;
csv模块;
以及一些Python自带的模块 。
安装Python并添加到环境变量 , pip安装需要的相关模块即可 。
拿到链接之后,接下来就是继续访问这些链接,然后拿到电影的下载链接
但是这里还是有很多的小细节,例如我们需要拿到电影的总页数,其次这么多的页面 , 一个线程不知道要跑到什么时候,所以我们首先先拿到总页码,然后用多线程来进行任务的分配
我们首先先拿到总页码,然后用多线程来进行任务的分配
总页数其实我们用re正则来获取
爬取的内容存取到csv,也可以写个函数来存取
开启4个进程来下载链接
您学废了吗?最后祝大家天天进步?。⊙癙ython最重要的就是心态 。我们在学习过程中必然会遇到很多难题 , 可能自己想破脑袋都无法解决 。这都是正常的 , 千万别急着否定自己 , 怀疑自己 。如果大家在刚开始学习中遇到困难 , 想找一个python学习交流环境,可以加入我们,领取学习资料,一起讨论,会节约很多时间,减少很多遇到的难题 。
python爬虫下载函数的介绍就聊到这里吧 , 感谢你花时间阅读本站内容,更多关于python爬虫app数据抓取、python爬虫下载函数的信息别忘了在本站进行查找喔 。

    推荐阅读