最近需要收集语料,因此学习了一些爬虫的知识,参考网上对糗事百科的爬虫,编写了如下代码
#!usr/bin/env python
# -*- coding: utf-8 -*-
import re
from urllib import request
for page in range(1, 2):
print(page)
url = 'http://www.qiushibaike.com/hot/page/' + str(page)
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
try:
req = request.Request(url, headers=headers)
with request.urlopen(req, timeout=5) as response:
content = response.read().decode('utf-8')
print(content)
pattern = re.compile(
'<div class="article block untagged mb15.*?id=(.*?)>.*?<div.*?<a.*?<img.*?<a.*?<h2>(.*?)</h2>'\
'.*?<a.*?<div.*?<span>(.*?)</span>.*?<!-- 图片或gif -->.*?<div(.*?)<span.*?number">(.*?)</i>'\
'.*?<i class="number">(.*?)</i>',
re.S)
items = re.findall(pattern, content)
for item in items:
if not re.search("thumb", item[3]):
print(item[0].replace("'", ""), item[1].strip(), item[2].strip(), item[4], item[5])
except request.URLError as e:
if hasattr(e, "code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)
对下面正则表达式的解释(引用http://cuiqingcai.com/990.html)
pattern = re.compile(
'<div class="article block untagged mb15.*?id=(.*?)>.*?<div.*?<a.*?<img.*?<a.*?<h2>(.*?)</h2>'\
'.*?<a.*?<div.*?<span>(.*?)</span>.*?<!-- 图片或gif -->.*?<div(.*?)<span.*?number">(.*?)</i>'\
'.*?<i class="number">(.*?)</i>',
re.S)
1).*? 是一个固定的搭配,.和*代表可以匹配任意无限多个字符,加上?表示使用非贪婪模式进行匹配,也就是我们会尽可能短地做匹配,以后我们还会大量用到 .*? 的搭配。
2)(.*?)代表一个分组,在这个正则表达式中我们匹配了五个分组,在后面的遍历item中,item[0]就代表第一个(.*?)所指代的内容,item[1]就代表第二个(.*?)所指代的内容,以此类推。
3)re.S 标志代表在匹配时为点任意匹配模式,点 . 也可以代表换行符。
以上代码在运行的过程中可能会存在问题(爬着爬着,就跑不动了),查找了一些资料后,给的原因是对于太过复杂的正则表达式,匹配时会出现这样的情况。
鉴于以上这种原因,我们采用BeautifulSoup可以解决,BeautifulSoup是根据html的格式来解析的。具体代码如下
#!usr/bin/env python
# -*- coding: utf-8 -*-
import re
from urllib import request
from bs4 import BeautifulSoup
def find_all(item, attr, c):
return item.find_all(attr, attrs={'class': c}, limit=1)
for page in range(1, 20):
print(page)
url = 'http://www.qiushibaike.com/hot/page/' + str(page)
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
try:
req = request.Request(url, headers=headers)
with request.urlopen(req, timeout=5) as response:
content = response.read().decode('utf-8')
soup = BeautifulSoup(content, 'html.parser')
all_div = soup.find_all('div', attrs={'class': re.compile('article block untagged mb15 .*?')})
for i, e_div in enumerate(all_div):
result = {}
result['id'] = e_div.attrs['id']
result['name'] = e_div.h2.string.strip()
cont = e_div.find_all('div', attrs={'class': 'content'})
result['content'] = cont[0].text.strip()
silme_comment = e_div.find_all('i', attrs={'class': 'number'})
result['silme_num'] = int(silme_comment[0].text.strip())
result['comment_num'] = int(silme_comment[1].text.strip())
print(result)
except request.URLError as e:
if hasattr(e, "code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)
本文介绍了使用Python爬取糗事百科网站数据的过程,对比了正则表达式和BeautifulSoup两种方法,解决了复杂正则表达式导致的问题。
575

被折叠的 条评论
为什么被折叠?



