爬虫那些事(一)

真正开始接触爬虫是七月下旬的开始吧,之前就觉得这东西挺有意思一直没空去学,这个七月中旬刚开始就来了学校,由于老师七月份没有安排太多的事,所以闲来无事就学起来了这个,加上在逛好友的博客时感觉他学了很多,也很激励我。

总的来说感觉还是很有意思的,希望可以坚持下去,以后即使有许多其他事要做也可以抽点时间来看。其实爬虫关于爬取静态网页的所有方法我都有了一个简单的了解,包括scrapy框架,不过框架用的不是很熟。在我目前的认知水平来看没有看出框架的优点,因为我常用的一些东西我都把它写成了函数,只需要复制一下就行了,感觉还挺快,可能这跟爬的都是简单的静态网页有关吧。

一、关于获取网页

其实获取网页有很多种方式,我看过崔庆才的html=requests.get(url,headers=hearders).text

我也看过pyquery库的直接用URL方式获取,但我猜pyquery库里的直接用URL方式打开肯定没有用浏览器代理,崔庆才的用requests.get的打开虽然比urllib.request.urlopen少两行代码,但我还是更习惯用我自己写的这个子函数,也许学的深入了会有所改变。

8月9日补充:requests库牛逼

def url_open(url):
	req=urllib.request.Request(url)
	req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36')
	iplist=['124.235.208.252:443','113.200.56.13:8010','218.60.8.98:3129']
	ip=random.choice(iplist)
	proxy_support = urllib.request.ProxyHandler({'http':ip})
	opener = urllib.request.build_opener(proxy_support)
	urllib.request.install_opener(opener)
	response=urllib.request.urlopen(req)
	html=response.read().decode('utf-8')
	return html

这是我常用的运用代理来访问打开网页的,上述三个代理IP可能不一定一直能用,比较免费的IP可能经常不靠谱,所以我也专门写了一个程序从西刺代理IP上爬取了他首页的所有IP地址,类型,以及是否高匿,由于并没有爬那种十分大的大工程,所以我也没有将二者结合在一个程序,其实因为我的这个ip是我手动输入的三个,所以我并没有加入异常处理,实际上有的IP并不一定能用导致你打不开网页,所以如果需要自己结合自动获取ip还是需要加入异常处理。

二、关于解析网页

在成功爬取网页之后,我们需要获取网页中我们需要的那部分东西,所以我们需要对网页做一个解析得到我们想要的。解析静态网页常用的我知道的有下面四种:正则表达式,Xpath,BeautifulSoup库,PyQuery库。其实并不一定每一个都要会,在我亲身试用了四种方法爬取同一个网页之后,我对此有了一个我的优先级排名:PyQuery库>Xpath=正则表达式>BeautifulSoup库

BeautifulSoup库:使用这个库需要初始化:from bs4 import BeautifulSoup,然后将需要解析的网页传入即可BeautifulSoup(html,’lxml’)这里支持多种解析方式,除了lxml还有’html.parser’,’xml’,’htm5lib’。各有优劣吧

         我为什么觉得这个库的优先级排在最后是因为我觉得他本身的运用soup.p(这里soup为解析后赋值的变量)这种选择网页节点的方式在复杂的网页并不实用,其获取文本为soup.p.string,获取节点属性为soup.p[‘name’]。总的来说非常繁琐,这个库里同样也为我们提供了查询方法soup.find_all(name,attrs,recursive,text,**kwargs)。括号里的为参数,并不需要全部输入。对于复杂的网页来说,感觉这种方法也不咋地,尤其是节点嵌套情况比较多,节点名也重复较多的时候。好在这个库还是提供了一个CSS选择器,用起来还是很好的,使用CSS选择器的时候需要调用select方法,eg:soup.select.(‘li’),返回的结果最后会组成一个列表,列表的元素为bs4Tag类型,但是由于PyQuery库也有选择器,所以我就果断放弃了这个库的继续研究与使用。

正则表达式:使用正则表达式只需要import re就行了正则表达式是很神奇的东西,他可以匹配任何字符,所以在仅仅只需获取一些简单的信息的时候,可以考虑使用正则表达式,虽然正则表达式的语法有很多,但我至今基本上都靠一个(.*?)走遍了许多网页,当然关于正则表达式还有一句俗语,当你有一个问题时,使用正则表达式你就有两个问题了,说明要学好正则表达式的匹配关系还是不简单的,不过这些表达式我觉得不需要去死记硬背,用的时候去查查就好了,补充说一下正则表达式语法: re.findall(‘p’,html),p为正则表达式,html为查找范围。

Xpath:使用Xpath来解析网页同样需要初始化一下:from lxml import etree      html=etree.HTML(url_open(url))。然后就可以对html进行操作了,一般我们解析网页无非就是找节点的文本或属性。下面就此举两个例子:

获取文本:html.xpath(//section/div/div/a/text()) 这里需要注意的是获取文本一定要定位到文本所属的那个子节点,不然可能返回\n

获取属性:html.xpath(//section/div[@class=”title-and”]/a/@href 获取属性的时候需要使用@字符,如果是前面有相同层级的节点需要选择对应的属性加上中括号[]  总的来说xpath还是非常的好用的

PyQuery库:照常初始化:from pyquery import PyQuery as pq,加个as pq是可以用pq来替代这个函数写起来简便,然后将html传入即可,html=pq(html).       PyQuery库同样是使用CSS选择器,并且和find函数搭配使用简单且功能强大。选择器的方法可以点CSS选择器进行跳转,就不再叙述,find函数可以筛选节点的所有子孙节点。find函数的参数也为选择器类型。但对于找到的多个节点来说,pq库的选择结果可能是多个节点但却并没有返回一个列表,所以需要进行遍历用for循环输出,需要调用.items()函数得到一个生成器,如果不调用输出的全是地址,为了方便说明举个例子如下:        

res=html(‘li > a’),for each in res.items(): print(each) 最后要说的同样是获取信息,如常用的属性和文本,紧跟上面的程序举例: 获取属性:res.attr.href   /   res.attr(‘href’) 获取文本:res.text()

最后补充一下审查元素查看网页的时候,选中节点点击右键会有xpath和选择器直接可以copy,有的地方稍作修改一下就行,非常方便。

三、存储信息

关于存储这方面,我看的还不多,用的最多的就是以.txt方式进行存储,以后再来进行补充,下面代码为存储txt文本代码

with open('filename.txt','a',encoding='utf-8') as f:
	f.write('\n'.join([a,b,c]))

上述代码中a,b,c为列表中的元素,通过join函数组合在一起写入,然后通过一个循环就可以把你所需要的列表元素全部写入了。

发表评论

邮箱地址不会被公开。 必填项已用*标注