Python 网页爬虫

一、要解决的问题

需要解决的是根据自定义的关键词自动搜索google学术,解析搜索到的网页,下载所有相应的论文的PDF链接。这里我们采用Python来实现,

二、Python入门

python 自动缩进:shift+table整块向左缩进,table向右缩进,在修改整块代码时很有用比如将函数变成单独执行时。

了解python的变量,包,函数定义等

三、网页知识

3.1 浏览网页的过程

打开网页的过程其实就是浏览器作为一个浏览的“客户端”,向服务器端发送了 一次请求,把服务器端的文件“抓”到本地,再进行解释、展现。

HTML是一种标记语言,用标签标记内容并加以解析和区分。

浏览器的功能是将获取到的HTML代码进行解析,然后将原始的代码转变成我们直接看到的网站页面。

3.2 URI和URL的概念

简单的来讲,URL就是在浏览器端输入的    http://www.baidu.com    这个字符串。

在理解URL之前,首先要理解URI的概念。

URL是URI的一个子集。它是Uniform Resource Locator的缩写,译为“统一资源定位 符”。

通俗地说,URL是Internet上描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上。

采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。

URL的一般格式为(带方括号[]的为可选项):

protocol :// hostname[:port] / path / [;parameters][?query]#fragment

URL的格式由三部分组成:

①第一部分是协议(或称为服务方式)。

②第二部分是存有该资源的主机IP地址(有时也包括端口号)。

③第三部分是主机资源的具体地址,如目录和文件名等。

第一部分和第二部分用“://”符号隔开,

第二部分和第三部分用“/”符号隔开。

第一部分和第二部分是不可缺少的,第三部分有时可以省略。

参考至:http://blog.csdn.net/pleasecallmewhy/article/details/8922826

四、网页爬虫

4.1 解决google无法登陆

因为要抓取的google学术的页面,但是google在中国屏蔽了,所以需要在电脑上先配置好goagent,然后进行代理配置,代码如下


proxy = urllib2.ProxyHandler({"http":"http://127.0.0.1:8087","https":"https://127.0.0.1:8087"})

opener = urllib2.build_opener(proxy)

urllib2.install_opener(opener)


4.2 解决抓取屏蔽

   对于少量的查询,但如果要进行上千上万次的查询,上面的方法就不再有效了, Google会检测你请求的来源,如果我们利用机器频繁爬取Google的搜索结果,不多久就Google会block你的IP,并给你返回503 Error页面。可以设置URL请求的headers,  伪装我们的user agent。简单的说,user agent就是客户端浏览器等应用程序使用的一种特殊的网络协议, 在每次浏览器(邮件客户端/搜索引擎蜘蛛)进行 HTTP 请求时发送到服务器,服务器就知道了用户是使用什么浏览器(邮件客户端/搜索引擎蜘蛛)来访问的。 有时候为了达到一些目的,我们不得不去善意的欺骗服务器告诉它我不是在用机器访问你。


user_agents = ['Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0', \

'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0', \

'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ \

(KHTML, like Gecko) Element Browser 5.0', \

'IBM WebExplorer /v0.94', 'Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en)', \

'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)', \

'Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14', \

'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) \

Version/6.0 Mobile/10A5355d Safari/8536.25', \

'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) \

Chrome/28.0.1468.0 Safari/537.36', \

'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld)']

proxy = urllib2.ProxyHandler({"http":"http://127.0.0.1:8087","https":"https://127.0.0.1:8087"})

opener = urllib2.build_opener(proxy)

urllib2.install_opener(opener)


4.3 正则表达式解析网页

使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。比如:现在的需求是要找到一个正则表达式来匹配后缀是“.pdf”的字符串。


inputURL = 'http://scholar.google.com/scholar?q=text+detection&btnG=&hl=en&as_sdt=0%2C5'

request = urllib2.Request(inputURL)

index = random.randint(0, 9)

user_agent = user_agents[index]

request.add_header('User-agent', user_agent)

f = urllib2.urlopen(request).read() #打开网页

print f

localDir = 'E:\download\\' #下载PDF文件需要存储在本地的文件夹

urlList = [] #用来存储提取的PDF下载的url的列表

for eachLine in f: #遍历网页的每一行

line = eachLine.strip() #去除行首位的空格,习惯性写法

if re.match('.*PDF.*', line): #去匹配含有“PDF”字符串的行,只有这些行才有PDF下载地址

wordList = line.split('\"') #以"为分界,将该行分开,这样就将url地址单独分开了

for word in wordList: #遍历每个字符串

if re.match('.*\.pdf$', word): #去匹配含有“.pdf”的字符串,只有url中才有

urlList.append(word) #将提取的url存入列表

for everyURL in urlList: #遍历列表的每一项,即每一个PDF的url

wordItems = everyURL.split('/') #将url以/为界进行划分,为了提取该PDF文件名

for item in wordItems: #遍历每个字符串

if re.match('.*\.pdf$', item): #查找PDF的文件名

PDFName = item #查找到PDF文件名

localPDF = localDir + PDFName #将本地存储目录和需要提取的PDF文件名进行连接

try:

urllib.urlretrieve(everyURL, localPDF) #按照url进行下载,并以其文件名存储到本地目录

except Exception, e:

continue


五、遇到的问题及解决

5.1 采用http协议

打开google的时候,如果用https协议无法打开网页取到内容,只有采用http协议才可以,原因可能是https采用加密协议。


# -*- coding: utf-8 -*-

"""

Created on Fri Feb 13 16:27:02 2015

@author: dwanminghuang

"""

import urllib #导入urllib模块

import urllib2 #导入urllib2模块

import re

import re, random, types #导入正则表达式模块:re模块

user_agents = ['Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0', \

'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0', \

'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ \

(KHTML, like Gecko) Element Browser 5.0', \

'IBM WebExplorer /v0.94', 'Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en)', \

'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)', \

'Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14', \

'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) \

Version/6.0 Mobile/10A5355d Safari/8536.25', \

'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) \

Chrome/28.0.1468.0 Safari/537.36', \

'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld)']

proxy = urllib2.ProxyHandler({"http":"http://127.0.0.1:8087","https":"https://127.0.0.1:8087"})

opener = urllib2.build_opener(proxy)

urllib2.install_opener(opener)

inputURL = 'http://scholar.google.com/scholar?q=text+detection&btnG=&hl=en&as_sdt=0%2C5'

request = urllib2.Request(inputURL)

index = random.randint(0, 9)

user_agent = user_agents[index]

request.add_header('User-agent', user_agent)

f = urllib2.urlopen(request).read() #打开网页

print f

localDir = 'E:\download\\' #下载PDF文件需要存储在本地的文件夹

urlList = [] #用来存储提取的PDF下载的url的列表

for eachLine in f: #遍历网页的每一行

line = eachLine.strip() #去除行首位的空格,习惯性写法

if re.match('.*PDF.*', line): #去匹配含有“PDF”字符串的行,只有这些行才有PDF下载地址

wordList = line.split('\"') #以"为分界,将该行分开,这样就将url地址单独分开了

for word in wordList: #遍历每个字符串

if re.match('.*\.pdf$', word): #去匹配含有“.pdf”的字符串,只有url中才有

urlList.append(word) #将提取的url存入列表

for everyURL in urlList: #遍历列表的每一项,即每一个PDF的url

wordItems = everyURL.split('/') #将url以/为界进行划分,为了提取该PDF文件名

for item in wordItems: #遍历每个字符串

if re.match('.*\.pdf$', item): #查找PDF的文件名

PDFName = item #查找到PDF文件名

localPDF = localDir + PDFName #将本地存储目录和需要提取的PDF文件名进行连接

try:

urllib.urlretrieve(everyURL, localPDF) #按照url进行下载,并以其文件名存储到本地目录

except Exception, e:

continue

 

 


posted @ 2015-02-20 18:13  dawnminghuang  阅读(919)  评论(0编辑  收藏  举报