一、准备工作
1.安装python
首先,下载Python3,这里使用Python3.7.1版本,64位。
地址链接:https://www.python.org/downloads/
双击打开,进行安装。特别注意:要勾选上"Add to Path"选项,否则后面会很麻烦。
2.安装pycharm
Pycharm是Python IDE的一种,可以帮助用户提高效率,比如调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制。此外,该IDE提供了一些高级功能,以用于支持Django框架下的专业Web开发
从网站下载pycharm,下载链接为:
https://www.jetbrains.com/pycharm/download/#section=windows
3.安装pip
4.安装第三方库
request对象是从客户端向服务器发出请求,包括用户提交的信息以及客户端的一些信息。客户端可通过HTML表单或在网页地址后面提供参数的方法提交数据,然后通过request对象的相关方法来获取这些数据。request的各种方法主要用来处理客户端浏览器提交的请求中的各项参数和选项。
在打开的setting界面中我们点击python的解释器,你会看到很多导入的第三方库,如下图所示,点击最右边的加号
左上角搜索request,添加该库
二、抓取分析
我们要抓取的目标站点为http://maoyan.com/board/4,打开之后的磅单信息如图。
排名第一的电影是霸王别姬,页面中显示的有效信息有影片名称、主演、上映时间、上映地区、评分、图片等信息。
将页面滚动到最下方,可以发现有分页的列表,直接点击第二页,可以发现页面的URL变成http://maoyan.com/board/4?offset=10,比之前的URL多了一个参数,那就是offset=10,而且目前的排行结果是排行11~20名的电影,初步推断这是一个偏移量的参数,再点击下一页,发现页面的URL变成了http://maoyan.com/board/4?offset=20,参数offset变成了20,而且显示的结果是排行21~30的电影。
可知offset代表偏移量,如果偏移量为n,则显示电影序号就是n+1到n+10,每页显示10个,所以,如果想获取TOP100电影,只需要分开请求10次,而10次的offset参数分别设置为0、10、20......90即可,这样获取不同的页面之后,再用正则表达式提取出相关信息,就可以得到TOP100的所有电影信息了。
三、获取url下的html
def get_one_page(url,offset):
try:#异处理常
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}
response = requests.get(url=url, headers=headers,params={"offset":offset})
if response.status_code==200:#请求成功
return response.text
pass
else:
return None
pass
pass
except RequestException as e:
return None
pass
pass
四、正则表达式解析网页
def parse_one_page(html):
pattern = '.*?board-index.*?">(\d+).*?data-src="(.*?)".*?/>.*?movie-item-info.*?title="(.*?)".*?star">' + \
'(.*?).*?releasetime">(.*?).*?integer">(.*?).*?fraction">(\d+).*? '
# re.S匹配多行
regex = re.compile(pattern, re.S)
items = regex.findall(html)
for item in items:
yield {
'index': item[0],
'thumb': get_large_thumb(item[1]),
'title': item[2],
'actors': item[3].strip()[3:],
'release_time': get_release_time(item[4].strip()[5:]),
'area': get_release_area(item[4].strip()[5:]),
'score': item[5] + item[6]
}
pass
五、写入文件
我们将爬取的结果写入文件,这里直接写入到一个csv文件
# 存储数据 def store_data(item): with open('movie.csv','a',newline='',encoding='utf-8') as data_csv: # dialect为打开csv文件的方式,默认是excel,delimiter="\t"参数指写入的时候的分隔符 try: csv_writer = csv.writer(data_csv) csv_writer.writerow([item['index'], item['thumb'], item['title'], item['actors'],item['release_time'],item['area'],item['score']]) except Exception as e: print(e) print(item) # 下载封面图 def download_thumb(title,url): try: response = requests.get(url=url) # 获取二进制数据 with open('thumb/'+title+'.jpg', 'wb') as f: f.write(response.content) f.close() except RequestException as e: print(e) pass
五、源代码
import csv import re import requests from requests import RequestException # 3.页面内容获取 # 请求一个页面返回响应内容 def get_one_page(url,offset): try: headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'} response = requests.get(url=url, headers=headers,params={"offset":offset}) if response.status_code==200: return response.text pass else: return None pass pass except RequestException as e: return None pass pass # 4.页面解析 # 解析一个页面 def parse_one_page(html): pattern = '
.*?board-index.*?">(\d+).*?data-src="(.*?)".*?/>.*?movie-item-info.*?title="(.*?)".*?star">' + \ '(.*?).*?releasetime">(.*?).*?integer">(.*?).*?fraction">(\d+).*? ' # re.S匹配多行 regex = re.compile(pattern, re.S) items = regex.findall(html) for item in items: yield { 'index': item[0], 'thumb': get_large_thumb(item[1]), 'title': item[2], 'actors': item[3].strip()[3:], 'release_time': get_release_time(item[4].strip()[5:]), 'area': get_release_area(item[4].strip()[5:]), 'score': item[5] + item[6] } pass pass # 获取上映时间 def get_release_time(data): pattern = '^(.*?)(\(|$)' regex = re.compile(pattern) w = regex.search(data) return w.group(1) # 获取上映地区 def get_release_area(data): pattern = '.*\((.*)\)' regex = re.compile(pattern) w = regex.search(data) if w is None: return'未知' return w.group(1) # 获取封面大图 def get_large_thumb(url): pattern = '(.*?)@.*?' regex = re.compile(pattern) w = regex.search(url) return w.group(1) # 存储数据 def store_data(item): with open('movie.csv','a',newline='',encoding='utf-8') as data_csv: # dialect为打开csv文件的方式,默认是excel,delimiter="\t"参数指写入的时候的分隔符 try: csv_writer = csv.writer(data_csv) csv_writer.writerow([item['index'], item['thumb'], item['title'], item['actors'],item['release_time'],item['area'],item['score']]) except Exception as e: print(e) print(item) # 下载封面图 def download_thumb(title,url): try: response = requests.get(url=url) # 获取二进制数据 with open('thumb/'+title+'.jpg', 'wb') as f: f.write(response.content) f.close() except RequestException as e: print(e) pass # 2.主调度程序 def main(): # 起始URL start_url="http://maoyan.com/board/4" for i in range(0,100,10): # 获取响应文本内容 html = get_one_page(url=start_url, offset=i) if html is None: print("链接:%s?offset=%s异常".format(start_url,i)) continue pass for item in parse_one_page(html=html): store_data(item) download_thumb(item["title"],item["thumb"]) pass pass if __name__ == '__main__': main() print("爬取完成!") pass