Данная статья является продолжением следующих двух статей
В эту серию входят следующие
- Возьмите Douban top250 с несколькими полями на одной странице
- Интегрировать в список
- сохранить как файл json
- определяется как функция
- Создать URL для многостраничного сканирования
- Перелистывание страниц многостраничного сканирования
- Получить данные вторичной страницы
- Оптимизируйте код с помощью генераторов
- Переписан как класс
В этой статье в основном говорится о
- Создать URL для многостраничного сканирования
- Перелистывание страниц многостраничного сканирования
- Получить данные вторичной страницы
В предыдущей статье мы определили функцию для получения данных одной страницы Douban top 250. Код выглядит следующим образом.
import requests # 导入网页请求库
from bs4 import BeautifulSoup # 导入网页解析库
import json
def start_requests(url):
r = requests.get(url)
return r.content
def parse(text):
soup = BeautifulSoup(text, 'html.parser')
movie_list = soup.find_all('div', class_ = 'item')
result_list = []
for movie in movie_list:
mydict = {}
mydict['title'] = movie.find('span', class_ = 'title').text
mydict['score'] = movie.find('span', class_ = 'rating_num').text
mydict['quote'] = movie.find('span', class_ = 'inq').text
star = movie.find('div', class_ = 'star')
mydict['comment_num'] = star.find_all('span')[-1].text[:-3]
result_list.append(mydict)
return result_list
def write_json(result):
s = json.dumps(result, indent = 4, ensure_ascii=False)
with open('movies.json', 'w', encoding = 'utf-8') as f:
f.write(s)
def main():
url = 'https://movie.douban.com/top250'
text = start_requests(url)
result = parse(text)
write_json(result)
if __name__ == '__main__':
main()
Далее нам нужно внести улучшения на основе этого кода.
Создать URL для многостраничного сканирования
В предыдущей статье мы усовершенствовали код сканера для обхода одной страницы. Теперь нам нужно просканировать информацию о 10 страницах и 250 фильмах. Обычно есть два способа просканировать несколько страниц с информацией. другой — перевернуть страницу, в этом разделе мы поговорим о том, как создать URL-адрес.
Мы можем посмотреть непосредственно на правила ссылок на этих страницах.
第一页 https://movie.douban.com/top250
第二页 https://movie.douban.com/top250?start=25&filter=
第三页 https://movie.douban.com/top250?start=50&filter=
第四页 https://movie.douban.com/top250?start=75&filter=
Можно обнаружить, что, кроме первой страницы, сзади изменено только одно число, и это арифметическая последовательность. Тогда мы можем предположить, может ли первая страница быть такой
https://movie.douban.com/top250?start=0&filter=
Введите эту ссылку в браузер и обнаружите, что это на самом деле первая страница, поэтому мы можем построить строку URL-адреса в соответствии с этим правилом, и для сканирования 250 фильмов требуется всего один цикл. Мы по-прежнему берем заголовок и распечатываем его.
import requests # 导入网页请求库
from bs4 import BeautifulSoup # 导入网页解析库
def start_requests(url):
r = requests.get(url)
return r.content
def parse(text):
soup = BeautifulSoup(text, 'html.parser')
movie_list = soup.find_all('div', class_ = 'item')
for movie in movie_list:
print(movie.find('span', class_ = 'title').text)
def main():
for i in range(10):
url = 'https://movie.douban.com/top250?start={}&filter='.format(i * 25)
text = start_requests(url)
parse(text)
if __name__ == '__main__':
main()
Затем нам нужно получить несколько полей и сохранить их в файле json.На данный момент нам нужно поместить несколько страниц информации о фильме в список и сохранить его в виде файла. (обратите внимание на комментарии в коде)
import requests # 导入网页请求库
from bs4 import BeautifulSoup # 导入网页解析库
import json
def start_requests(url):
r = requests.get(url)
return r.content
def parse(text):
soup = BeautifulSoup(text, 'html.parser')
movie_list = soup.find_all('div', class_ = 'item')
for movie in movie_list:
mydict = {}
mydict['title'] = movie.find('span', class_ = 'title').text
mydict['score'] = movie.find('span', class_ = 'rating_num').text
quote = movie.find('span', class_ = 'inq')
mydict['quote'] = quote.text if quote else None # 抓取10页就总会遇到这种特殊情况要处理
star = movie.find('div', class_ = 'star')
mydict['comment_num'] = star.find_all('span')[-1].text[:-3]
result_list.append(mydict) # 向全局变量result_list中加入元素
def write_json(result):
s = json.dumps(result, indent = 4, ensure_ascii=False)
with open('movies.json', 'w', encoding = 'utf-8') as f:
f.write(s)
def main():
for i in range(10):
url = 'https://movie.douban.com/top250?start={}&filter='.format(i * 25)
text = start_requests(url)
parse(text)
write_json(result_list) # 所有电影都存进去之后一起输出到文件
if __name__ == '__main__':
# 初始化,注意不要在main()函数里定义,因为那里不是全局变量,其他函数无法调用
result_list = []
main()
Перелистывание страниц многостраничного сканирования
Принцип перелистывания страниц заключается в том, чтобы сканировать URL-адрес следующей страницы при сканировании информации одной страницы, а затем сканировать URL-адрес, который был просканирован. Этот метод подходит для веб-сайтов с тегами «следующая страница» и обычно используется, когда URL-адрес веб-страницы не может быть создан.
Таким образом, вы должны обратить внимание на то, есть ли следующая страница, чтобы судить
import requests # 导入网页请求库
from bs4 import BeautifulSoup # 导入网页解析库
import json
def start_requests(url):
r = requests.get(url)
return r.content
def parse(text):
soup = BeautifulSoup(text, 'html.parser')
movie_list = soup.find_all('div', class_ = 'item')
for movie in movie_list:
mydict = {}
mydict['title'] = movie.find('span', class_ = 'title').text
mydict['score'] = movie.find('span', class_ = 'rating_num').text
quote = movie.find('span', class_ = 'inq')
mydict['quote'] = quote.text if quote else None # 抓取10页就总会遇到这种特殊情况要处理
star = movie.find('div', class_ = 'star')
mydict['comment_num'] = star.find_all('span')[-1].text[:-3]
result_list.append(mydict) # 向全局变量result_list中加入元素
nextpage = soup.find('span', class_ = 'next').a # 找到“下一页”位置
if nextpage:# 找到的就再解析,没找到说明是最后一页,递归函数parse就运行结束
nexturl = baseurl + nextpage['href']
text = start_requests(nexturl) # 多次使用这个函数,可以看出定义函数的好处,当请求更复杂的时候好处更明显
parse(text)
def write_json(result):
s = json.dumps(result, indent = 4, ensure_ascii=False)
with open('movies.json', 'w', encoding = 'utf-8') as f:
f.write(s)
def main():
text = start_requests(baseurl)
parse(text)
write_json(result_list) # 所有电影都存进去之后一起输出到文件
if __name__ == '__main__':
baseurl = 'https://movie.douban.com/top250'
result_list = []
main()
Получить данные вторичной страницы
мы обычно звонимэтоСтраницы в виде списка являются страницами первого уровня, аэтоОтдельная страница для каждого объекта является вторичной страницей. В предыдущей статье мы извлекали информацию только со страницы первого уровня, но информация, отображаемая на странице первого уровня, ограничена, поэтому иногда нам нужно войти на собственную страницу каждого объекта, чтобы получить больше информации.
Далее берем страницы деталей 2-х страниц (50) фильмов, потому что разницы в коде между 2-мя страницами и 10-ю страницами нет, а на 10-ти страницах придется посещать сайт более 200 раз, и краулер может быть Эта проблема не относится к теме этой статьи, поэтому мы пропустим ее и просканируем только две страницы.
Мы получаем три показателя: название, время выпуска и продолжительность фильма.
Логика кода состоит в том, чтобы получить ссылку на каждый фильм, затем запросить каждую ссылку и проанализировать каждую страницу сведений о фильме для получения данных.
код показывает, как показано ниже
import requests # 导入网页请求库
from bs4 import BeautifulSoup # 导入网页解析库
import json
# 发起请求
def start_requests(url):
print(url) # 用这条命令知道当前在抓取哪个链接,如果发生错误便于调试
r = requests.get(url)
return r.content
# 解析一级网页,获取url列表
def get_page(text):
soup = BeautifulSoup(text, 'html.parser')
movies = soup.find_all('div', class_ = 'info')
pages = []
for movie in movies:
url = movie.find('div', class_ = 'hd').a['href']
pages.append(url)
return pages
# 解析二级网页,获取信息
def parse_page(text):
soup = BeautifulSoup(text, 'html.parser')
mydict = {}
mydict['title'] = soup.find('span', property = 'v:itemreviewed').text
mydict['duration'] = soup.find('span', property = 'v:runtime').text
mydict['time'] = soup.find('span', property = 'v:initialReleaseDate').text
return mydict
# 将数据读取到json文件中
def write_json(result):
s = json.dumps(result, indent = 4, ensure_ascii=False)
with open('movies.json', 'w', encoding = 'utf-8') as f:
f.write(s)
def main():
for i in range(7, 9):
url = 'https://movie.douban.com/top250?start={}&filter='.format(i * 25)
text = start_requests(url)
pageurls = get_page(text) # 解析一级页面
for pageurl in pageurls: # 解析二级页面
page = start_requests(pageurl)
mydict = parse_page(page)
result_list.append(mydict)
write_json(result_list) # 所有电影都存进去之后一起输出到文件
if __name__ == '__main__':
result_list = []
main()
В приведенном выше коде часто определяются некоторые глобальные переменные, и я чувствую, что дизайн кода будет несколько неэлегантным.В следующей статье эта проблема будет решена путем определения генераторов и классов.
Информация о столбце
Главная страница колонки:программирование на питоне
Каталог столбцов:содержание
Каталог сканера:Каталог серий Рептилии
Примечания к выпуску:Примечания к выпуску программного обеспечения и пакетов