Простая Python l oop проблема, не могу придумать правильный ответ - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь webscrape https://old.reddit.com/r/all/ и получаю записи на первой странице.

Когда я запускаю свой код, он работает, но для post_text он копирует только последние пост на странице Reddit 25 раз. Я знаю, что это потому, что он получает запись, а затем публикует ее каждый раз через l oop.

import requests
import urllib.request
from bs4 import BeautifulSoup as soup

my_url = 'https://old.reddit.com/r/all/'

request = urllib.request.Request(my_url,headers={'User-Agent': 'your bot 0.1'})
response = urllib.request.urlopen(request)
page_html = response.read()

page_soup = soup(page_html, "html.parser")

posts = page_soup.findAll("div", {"class": "top-matter"})
post = posts[0]

authors = page_soup.findAll("p", {"class":"tagline"})
author = authors[0]

filename = "redditAll.csv"
f = open(filename, "w")
headers = "Title of the post, Author of the post\n"
f.write(headers)

for post in posts:
    post_text = post.p.a.text.replace(",", " -")

for author in authors:
    username = author.a.text

    f.write(post_text + "," + username + "\n")
f.close()

Изменил это

for post in posts:
    post_text = post.p.a.text.replace(",", " -")

for author in authors:
    username = author.a.text

На это

for post, author in zip(posts, authors):
    post_text = post.p.a.text.replace(",", " -")
    username = author.a.text

Ответы [ 3 ]

1 голос
/ 17 апреля 2020

LЭто верно, но я бы посчитал это более идиоматическим c.

for post, author in zip(posts, authors):
    post_text = post.p.a.text.replace(",", " -")
    username = author.a.text

    f.write(post_text + "," + username + "\n")
1 голос
/ 17 апреля 2020

Проблема здесь в том, что вы записываете в файловый объект в пределах секунды значение l oop for author in authors, поэтому вы действительно напишите последнее значение post_text несколько раз.

Если вы хотите объединить авторов и сообщения, вы можете сжать их, и они будут перебирать их (при условии, что они имеют одинаковую длину)


for author, post in zip(posts, authors):
    write.(f 'author: {author}, post: {post}')

Я бы также рекомендовал записывать в файл с помощью диспетчера контекста.

например.

with open('filename.txt', 'w') as f:
   f.write('stuff')
1 голос
/ 17 апреля 2020

Вы делаете две петли отдельно. В приведенном ниже коде вы просматриваете каждый пост и присваиваете строку post_text, но больше ничего не делаете с ним. Когда это l oop выполнено, post_text - это последнее, что ему было назначено, как прежде, чем оно переместится в авторов l oop и записывает строку с каждым автором и строку, которую вы сохранили в post_text.

for post in posts:
    post_text = post.p.a.text.replace(",", " -")

for author in authors:
    username = author.a.text

    f.write(post_text + "," + username + "\n")

Предполагая, что в постах и ​​авторах одинаковое количество элементов, вы можете исправить это следующим образом:

for i in range(len(posts)):
    post_text = posts[i].p.a.text.replace(",", " -")
    username = authors[i].a.text

    f.write(post_text + "," + username + "\n")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...