爬取的是58同城租房信息,执行程序后,只是光标在闪烁,长时间不显示结果。由于状态码为200,所以考虑正则表达式是否合理。由于网页源代码中有大量的换行符,一开始匹配用的是[\s\S]*?,并没有考虑所要获取的内容基本都是独一行,所以精简后的正则在获取内容时用(.*?)。再次执行程序,结果就出来了。
本人初学爬虫,如有更好的解决方法,欢迎评论交流!
原来的正则表达式为:
pat = r'<li[\s\S]*?<img[\s\S]*?lazy_src="([\s\S]*?)"[\s]*?src="[\s\S]*?">[\s\S]*?rel="nofollow" >([\s\S]*?)</a>[\s\S]*?room strongbox">([\s\S]*?) ([\s\S]*?)</p>[\s\S]*?<b class="strongbox">([\s\S]*?)</b>[\s\S]*?</li>'
精简后的表达式为:
pat = r'<li[\s\S]*?_src="(.*?)"[\s\S]*?_blank".*?\n([\s\S]*?)</a[\s\S]*?x">(.*?) (.*?)</p[\s\S]*?x">([\d]*?)</b'
完整程序;
import requests
from requests.exceptions import RequestException
import re,json,os
def getpage(num):
'''获取指定页面信息'''
url = 'https://bj.58.com/chuzu/pn'+str(num)+'/?ClickID=2'
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36"
}
try:
res = requests.get(url,headers=headers)
if res.status_code == 200:
#获取数据
html = res.content.decode('utf-8')
#获取整页数据太慢,只其中的部分数据
html2 = html[25050:45050]
#解析数据
# pat = r'<li[\s\S]*?<img[\s\S]*?lazy_src="([\s\S]*?)"[\s]*?src="[\s\S]*?">[\s\S]*?rel="nofollow" >([\s\S]*?)</a>[\s\S]*?room strongbox">([\s\S]*?) ([\s\S]*?)</p>[\s\S]*?<b class="strongbox">([\s\S]*?)</b>[\s\S]*?</li>'
#精简后的re表达式
pat = r'<li[\s\S]*?_src="(.*?)"[\s\S]*?_blank".*?\n([\s\S]*?)</a[\s\S]*?x">(.*?) (.*?)</p[\s\S]*?x">([\d]*?)</b'
dlist = re.findall(pat,html,re.M)
x =int(str(num)+'01')
for item in dlist:
yield{
' | 标题:':item[1].strip(),
' | 户型:':item[2].strip()+','+item[3].strip(),
' | 价格:':item[4]+'元/月',
' | 图片:':item[0],
}
#获取图片
img = requests.get('https:'+item[0])
with open('./images/req%s.jpg' % x,'wb') as f:
f.write(img.content)
f.close()
x+=1
# print('标题:'+item[1].strip()+' | 户型:'+item[2].strip()+','+item[3].strip()+' | 价格:'+item[4]+'元/月')
print("共"+str(len(dlist))+"条数据")
else:
print('网页爬取错误1')
return None
except RequestException as e:
print(e)
return None
def writeFile(content):
'''将获取的信息写入文件'''
with open('./58req.txt','a',encoding='utf-8') as f:
f.write(json.dumps(content,ensure_ascii=False) + "\n")
def main(num):
'''主函数'''
#判断当前路径是否存在images文件夹,没有则创建
if not os.path.exists('./images'):
os.mkdir('./images')
for item in getpage(num):
writeFile(item)
if __name__ == '__main__':
num = int(input('请输入你要查看的页面(1-70):'))
main(num)