端午节要到了,节假日前各种事情也慢慢变少了。
今天也先做点基础爬虫吧。
上次爬京东上的图片的时候,明显是用的投机取巧的方式进行的网页跳转,没有做到真正意义上一个链接一个链接爬下去。这次先从一个页面上爬取所有链接吧。
#python爬虫第十二课,爬取链接
import re
import urllib.request
def getlink(url):
headers =("User-Agent","Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36")
opener = urllib.request.build_opener()
opener.addheaders = [headers]
urllib.request.install_opener(opener)
file = urllib.request.urlopen(url)
data=str(file.read())
#a = open("D:/test.txt","w")
#a.write(data)
#a.close()
#print(data)
#pat = '(https?://[^\s)";]+\.(\w|/)*)'
pat = ''
link = re.compile(pat).findall(data)
link=list(set(link))
return link
url = "http://blog.csdn.net/"
linklist = getlink(url)
n=0
for link in linklist:
print(link)
#print(link[0])
n += 1
print(n)
这次爬的是csdn的blog主页上的所有链接。看我的两个不一样的pattern,其实抓链接有两种方式,一种是通过观察它在xml文件中的位置,第二种是通过它的形态。两种方法大同小异,但是要注意的是,用第一种方法可能会抓到相同位置上的其他东西,第二种方法可能抓到不想要的但是格式一样的东西。
然后,就是今次的重头戏了。糗事百科的笑话抓取。
我上次粗浅地学习爬虫的时候好像也是用的糗百做的练手。这次明显感觉,抓糗百变难了。难点在两个地方,一是现在糗百似乎有特别的防爬虫机制,有的header加上去之后爬了几页仍然会报403 error。二是糗百的网页似乎并不全是utf-8编码的,转码的时候一定要忽略掉无法转码的内容,否则也会报错。糗百的前端工程师们长点心吧。
抓之前先明确目标,这次我们要抓的是糗百的内容和对应的用户名。跳转页面的方法和之前抓取京东的手机图片一样,只需要用for循环即可。但是内容和用户名怎么对应起来,就可能有问题了。
一开始我是分别抓取user和content,采用exec的方式来逐一匹配user和content,但是很快就会有问题,最大的问题在于,分开抓取的user和content可能无法匹配上,尝试了多个正则表达式后仍然不尽人意。经常是抓到20个user,但是抓到了30多个content。
于是还是考虑分两步过滤的办法,第一步是把每一个user/content的组合所在的部分先抓起来,然后在循环这个组合的list时,单独抓出user和content,这样就保证了user和content的对照。这样抓还有一个好处,就是后期如果想要看每个内容的评论数和浏览数时,只需再添加两个正则表达式即可完美对照抓取。我们毕竟只是在学爬虫,后期的数据分析等学完再说吧。
#python爬虫第十三课 糗百
import urllib.request
import re
def getcontent(url,page):
headers = ("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0")
opener = urllib.request.build_opener()
opener.addheaders = [headers]
urllib.request.install_opener(opener)
file = urllib.request.urlopen(url).read()
data = file.decode('utf-8',errors="ignore")
#pat_user = 'target="_blank" title="(.*?)">'
pat_user = '
(.*?)
'pat_content = '
pat1 = '
jokelist = re.compile(pat1,re.S).findall(data) # re.S .匹配换行符
a = 1
#file = open("D://test.txt", "w")
for joke in jokelist:
user = re.compile(pat_user).findall(joke)
content = re.compile(pat_content).findall(joke)
#print(user)
#print(content)
#print("用户" + str(page) +"."+ str(a) + ": " + user[0] + "\n",file=file)
#print("内容: \n",file=file)
#print(content[0].encode("utf-8",errors="ignore").decode(),file=file)
#print("\n",file=file)
print("用户" + str(page) + "." + str(a) + ": " + user[0] + "\n")
print("内容: \n")
print(content[0].encode("utf-8", errors="ignore").decode())
print("\n")
a+=1
#file.close()
for i in range(1,30):
url = "http://www.qiushibaike.com/8hr/page/"+str(i)+"/"
getcontent(url,i)